Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer is missing a nullability type specifier

In Xcode 7 GM I started to get this warning:

Pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)

In the following function declaration (NSUserDefaults extension)

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

Screenshot

Why this warning is showing and how should I fix it?

like image 517
kelin Avatar asked Sep 12 '15 13:09

kelin


2 Answers

You can use the following macros around blocks of declarations (functions and variables) in objective c headers:

NS_ASSUME_NONNULL_BEGIN   NS_ASSUME_NONNULL_END 

You need to then add nullable annotations for references that can be nil within that block. This applies to both function parameters and variable declarations.

As 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* The why??? is because for an objective-c class to be interoperable with swift, you need to declare nullability so that the compiler knows to treat properties as swift optionals or not. Nullable objective c properties are known as optionals in swift and using these macros in conjunction with the nullable declarators for properties allows the compiler to treat them as optionals (Optionals are monads - an object that wraps up either the object or nil).

like image 116
Kevin Avatar answered Oct 05 '22 17:10

Kevin


You need to specify nullable also for the handlers/blocks

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

Why? It's due to Swift. Swift allows optional parameters (?), which Objective-C does not. This is done as a bridge between the both of them for the Swift compiler to know those parameters are optional. A 'Nonnull' will tell the Swift compiler that the argument is the required. A nullable that it is optional

For more info read: https://developer.apple.com/swift/blog/?id=25

like image 22
Ares Avatar answered Oct 05 '22 15:10

Ares