__nullable和__nonnull是Xcode 6.3引入的新的关键字。
顾名思义,__nullable表示可以为nil,__nonnull则反之。
举例代码如下:
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
[selfsetName:nil];//会产生警告;
}
- (void)setName:(NSString * __nonnull)name {
NSLog(@"%@",name);
}
@end
__nullable也可以写成nullable,__nonnull也可以写成nonnull,但是位置不同。写法如下:
- (void)setName:(nonnullNSString * )name {
NSLog(@"%@",name);
}
如果按照下面的方式写,会报错。
- (void)setName:(NSString *nonnull)name {
NSLog(@"%@",name);
}
也可以修饰属性,如下:
@interfaceViewController ()
@property (strong,nonatomic,nonnull)NSString *name1;
@property (strong,nonatomic,__nonnull)NSString *name2;
@property (__nonnull,strong,nonatomic)NSString *name3;
@property (nonnull,strong,nonatomic)NSString *name4;
@property (strong,nonatomic)NSString * __nonnull name5;
@end
但如下的写法,是错误的:
@property (strong,nonatomic)NSString * nonnull name6;
@property (strong,nonatomic)nonnull NSString *name7;
然后说下 NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END
Nonnull区域设置(Audited Regions)
如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END。
在
#define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
#define NS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
NS_ASSUME_NONNULL_BEGIN @interface TestNullabilityClass () @property (nonatomic, copy) NSArray * items; - (id)itemWithName:(nullable NSString *)name; @end NS_ASSUME_NONNULL_END
在上面的代码中,items属性默认是nonnull的,itemWithName:方法的返回值也是nonnull,而参数是指定为nullable的。
不过,为了安全起见,苹果还制定了几条规则: