wake-up-neo.com

Dem Zeiger fehlt ein NULL-Typ-Bezeichner

In Xcode 7 GM Ich fing an, diese Warnung zu bekommen:

Dem Zeiger fehlt ein NULL-Typ-Bezeichner (_Nonnull, _Nullable oder _Null_unspecified)

In der folgenden Funktionsdeklaration (Erweiterung NSUserDefaults)

- (void)setObject:(nullable id)value
           forKey:(NSString *)defaultName
    objectChanged:(void(^)(NSUserDefaults *userDefaults, id value))changeHandler
    objectRamains:(void(^)(NSUserDefaults *userDefaults, id value))remainHandler;

Warum wird diese Warnung angezeigt und wie kann ich sie beheben?

59
kelin

Sie müssen nullable auch für die Handler/Blöcke angeben

- (void)setObject:(nullable id)value
           forKey:(nonnull NSString *)defaultName
    objectChanged:(nullable void(^)(NSUserDefaults *userDefaults, id value))changeHandler
    objectRamains:(nullable void(^)(NSUserDefaults *userDefaults, id value))remainHandler;

Warum? Es ist Swift zu verdanken. Swift erlaubt optionale Parameter (?), Die von Objective-C nicht unterstützt werden. Dies geschieht als Brücke zwischen beiden, damit der Swift) - Compiler Bescheid weiß Diese Parameter sind optional. Ein 'Nonnull' teilt dem Swift) - Compiler mit, dass das Argument erforderlich ist

Weitere Informationen finden Sie unter: https://developer.Apple.com/Swift/blog/?id=25

55
Ares

Sie können die folgenden Makros für Deklarationsblöcke (Funktionen und Variablen) in Objective C-Headern verwenden:

NS_ASSUME_NONNULL_BEGIN 

NS_ASSUME_NONNULL_END

Anschließend müssen Sie nullfähige Anmerkungen für Verweise hinzufügen, die in diesem Block null sein können. Dies gilt sowohl für Funktionsparameter als auch für Variablendeklarationen.

Wie in:

@interface SMLBaseUserDetailsVC : UIViewController < UICollectionViewDelegate>
NS_ASSUME_NONNULL_BEGIN

@property (nonatomic, readonly) IBOutlet UIScrollView *detailsScrollView;
@property (nonatomic, readonly) IBOutlet UICollectionView *photoCV;
@property (nonatomic, weak, readonly) SMLUser *user;
- (IBAction)flagUser:(id)sender;
- (IBAction)closeAction:(nullable id)sender;
- (void) prefetchPhotos;

NS_ASSUME_NONNULL_END

@end

Bearbeiten * Das Warum ??? Dies liegt daran, dass für die Interoperabilität einer Objective-C-Klasse mit Swift die NULL-Fähigkeit deklariert werden muss, damit der Compiler Eigenschaften als Swift optionals oder nicht. NULL-fähige Objective-C-Eigenschaften werden als optionals bezeichnet in Swift und die Verwendung dieser Makros in Verbindung mit den nullwertfähigen Deklaratoren für Eigenschaften ermöglichen es dem Compiler, sie als optionale Werte zu behandeln (optionale Werte sind Monaden - ein Objekt, das entweder das Objekt oder den Wert nil umschließt).

54
Kevin

Die korrekte, vom Compiler akzeptierte Arbeitsmethoden-Deklaration:

- (void)setObject:(nullable id)value
           forKey:(nonnull NSString *)defaultName
    objectChanged:(nullable void(^)(NSUserDefaults *_Nonnull userDefaults, id _Nullable value))changeHandler
    objectRamains:(nullable void(^)(NSUserDefaults *_Nonnull userDefaults, id _Nullable value))remainHandler;
14
kelin

Ich poste diese Antwort, um zu erklären, warum _Nonnull Oder nullable hinzugefügt werden sollten.

Laut diesem Blog: https://developer.Apple.com/Swift/blog/?id=25

Eines der großartigen Dinge an Swift ist, dass es transparent mit Objective-C-Code zusammenarbeitet, sowohl mit vorhandenen Frameworks, die in Objective-C geschrieben wurden, als auch mit Code in Ihrer App. In Swift Es gibt einen starken Unterschied zwischen optionalen und nicht optionalen Referenzen, z. B. NSView vs. NSView?, während Objective-C beide dieser beiden Typen als NSView * darstellt. Da der Swift Compiler nicht sicher sein kann, ob ein bestimmtes NSView * Optional ist oder nicht, wird der Typ implizit in Swift) eingefügt optional ausgepackt, NSView!.

alles für Swift.

9
fishtrees

So deaktivieren Sie diese Warnung für das gesamte Projekt

  1. Gehen Sie zu Build Settings

  2. Stellen Sie sicher, dass Sie die Registerkarte "Alle" nicht "Einfach" oder "Angepasst" anzeigen.

  3. Suche nach dem Feld Other Warning Flags

  4. Fügen Sie die folgende Flagge hinzu: -Wno-nullability-completeness.

  5. Jetzt bereinigen und bauen (cmd + shift + k dann cmd + r)

    - beachte, es kann ein paar Sekunden dauern, bis die Warnungen verschwunden sind, auch wenn du fertig bist. Bei mir dauert es ungefähr 15 Sekunden, bis xCode vollständig aktualisiert ist.

3
Albert Renshaw