In diesem Code
%Vor%Ich habe diesen Fehler
Inkompatible Block-Zeigertypen, die 'id (^ __ strong) (void)' mit einem Ausdruck vom Typ 'void * (^) (void)'
initialisieren
Also muss ich nil
explizit auf id
type
macht den Compiler glücklich. Warum kaufen nil
ist nicht id
type?
Und für diesen Code
%Vor%Implizite Konvertierung des Objective-C-Zeigertyps 'NSObject *' in C-Zeigertyp 'typeof (((void *) 0))' (alias 'void *') erfordert eine überbrückte Umwandlung
Das heißt nil
ist (void *)0
, aber ist nicht nur das gleiche wie NULL
? Ich denke, nil
sollte (id)0
und Nil
sollte (Class)0
sein?
Ich verwende Xcode 4.6.2
Compiler: Apple LLVM Version 4.2 (clang-425.0.28) (basierend auf LLVM 3.2svn)
Sie verwenden einen abgeleiteten Rückgabetyp für Ihr Blockliteral, müssen dies aber nicht tun.
Der richtige Weg, um diesen Fehler zu entfernen, ist die Angabe eines Rückgabetyps für das Blockliteral:
%Vor%Wenn ein Block seinen Rückgabetyp weglässt, wird es jetzt die Aufgabe des Compilers, basierend auf den Rückgaben in seinem Rumpf den Typ des Blocks abzuleiten. Aber unglücklicherweise sucht CLANG nach den vollständig verfallenen Formen seiner zurückgegebenen Typen, was zu seltsamen Inkonsistenzen führt.
Das am besten zugängliche Beispiel ist das Sortieren eines Arrays. Der Typ des Vergleichsblocks ist NSComparisonResult(^)(id obj, id obj2)
. Wenn Sie jedoch den Rückgabetyp NSComparisonResult auslassen, erhält der Compiler whiny:
Dieser Block zerfällt in einen Block vom Typ int(^)(id obj, id obj2)
, den der Compiler als inkompatibel ansieht (wohl werden enums nur als ints bezeichnet, also sollte dies kompiliert werden).
Auf dieselbe Weise verfällt die ID in objc_object*
, die immer weiter abfällt, bis sie void*
erreicht, oder "irgendein generischer Zeiger" (gemäß der C-Sprachenspezifikation). void * und id sind ganz sicher nicht vom selben Typ. Um dies zu umgehen, müssen Sie dem Compiler versprechen, dass der zurückgegebene Typ wirklich das ist, was er ist, und der einzige Weg dazu besteht in der Umwandlung.
LLVM 5.0 behebt das, indem es die Inferenzen des Compilers viel intelligenter macht.
Ich weiß nicht, warum nil ist #define nil NULL
in der Apple-Header (das ist eine Tatsache, aber ich weiß nicht den Grund, warum es nicht (id)0
wie man erwarten würde), aber ich hatte nie den Fehler, den Sie sind Erwähnung in der neuesten Version von Xcode und dem Compiler.
Ich glaube, ich erinnere mich an einen Fehler in früheren Versionen des Legacy-Compilers, der implizite Umwandlungen wie diese in Blöcke von Rückgabetypen und allem falsch interpretierte.
Welchen Compiler benutzen Sie? LLVM-GCC 4.2? oder Apple LLVM 4.2? Ein älterer Compiler? Überprüfen Sie die Build-Einstellungen Ihres Projekts. Ich empfehle, zu Apple LLVM zu wechseln und zu überprüfen, ob das Ihr Problem löst .
(Tatsächlich wird LLVM-GCC nur für den Übergang vom alten GCC zum neuen LLVM seit einigen Versionen von Xcode verwendet, ist aber veraltet und soll in der nächsten Version von Xcode entfernt werden )
Tags und Links objective-c objective-c-blocks null