2015-09-12 1 views
49

In Xcode 7 GM ho cominciato ad avere questa avvertenza:Pointer manca un tipo di supporto di valori Null specificatore

puntatore manca un tipo di supporto di valori Null specificatore (_Nonnull, _Nullable, o _Null_unspecified)

Nel seguente dichiarazione di funzione (NSUserDefaults estensione)

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

Perchè questo avviso sta mostrando e come devo risolvere il problema?

risposta

48

è necessario specificare nullable anche per i gestori/blocchi

- (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; 

Perché? È dovuto a Swift. Swift consente parametri opzionali (?), Che Objective-C non ha. Questo è un ponte tra entrambi per il compilatore Swift per sapere che questi parametri sono opzionali. Un 'Nonnull' dirà al compilatore Swift che l'argomento è obbligatorio. Un nullable che è facoltativo

Per maggiori informazioni leggere: https://developer.apple.com/swift/blog/?id=25

+0

Devo aggiungere che il compilatore è anche punti per specificare qualcosa per i parametri del blocco. – kelin

+38

perché ????????????????? – mskw

+1

Stai chiedendo perché è necessario specificarli? A causa dell'interoperabilità con il compilatore Swift. Determina se l'API è esposta come facoltativa o meno. Vedere il post del blog Apple qui: https://developer.apple.com/swift/blog/?id=25 – bandejapaisa

13

la correttezza, lavorando dichiarazione di metodo, accettata dal compilatore:

- (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; 
42

È possibile utilizzare le seguenti macro intorno blocchi di dichiarazioni (funzioni e variabili) in intestazioni obiettive c:

NS_ASSUME_NONNULL_BEGIN 

NS_ASSUME_NONNULL_END 

È necessario aggiungere quindi annotazioni annullabili per riferimenti che possono essere nulli all'interno di quel blocco. Questo vale sia per i parametri di funzione sia per le dichiarazioni variabili.

come 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 

Edit * Il perché ??? è perché per una classe ogg-c essere interoperabile con swift, è necessario dichiarare il nullability in modo che il compilatore sappia trattare le proprietà come swift optionals o meno. Le proprietà oggettive cnullabili sono conosciute come optionali in swift e l'uso di queste macro in congiunzione con i dichiaratori nullable per le proprietà consente al compilatore di considerarle come optionali (Optionals sono monadi - un oggetto che avvolge l'oggetto o nil).

+0

Ancora una volta, penso che avresti dovuto spiegare perché devi usare i macro attorno ai blocchi di dichiarazione ??? –

8

Ho pubblicato questa risposta per spiegare perché dovrebbe aggiungere _Nonnull o nullable.

Secondo questo blog: https://developer.apple.com/swift/blog/?id=25

Una delle grandi cose su Swift è che interagisce in modo trasparente con il codice Objective-C, entrambi i quadri esistenti scritte in Objective-C e il codice nella vostra applicazione. Tuttavia, in Swift c'è una forte distinzione tra riferimenti opzionali e non opzionali, ad es. NSView rispetto a NSView?, mentre Objective-C rappresenta entrambi di questi due tipi come NSView *. Poiché il compilatore Swift non può essere sicuro che un particolare NSView * sia opzionale o meno, il tipo viene portato in Swift come facoltativo da scartare facoltativamente, NSView!.

è tutto per Swift.