1.场景:
当在一个类中对属性,或者参数使用__nullable 或者 __nonnull 关键字修饰的时候,发现之后整个类都会发出警告,提示我们需要对所有的属性,参数,返回值都要指明是否为null 。
2.原因说明:
从xcode6.3开始 为了让OC也能有swift的?和!的功能,你在声明一个属性的时候加上 __nullable(?可以为空)与__nonnull(!不能为空) 如果放在@property里面的话不用写下划线;
oc 类里面的指针没有使用该关键字的话,默认是nullable
3.解决办法:
苹果提供了一对宏来批处理该问题-> NS_ASSUME_NONNULL_BEGIN,
NS_ASSUME_NONNULL_END
在这两个宏之间的代码,所有 简单指针 对象都被假定为nonnull,因此我们只需要去指定那些nullable的指针。如下代码所示
NS_ASSUME_NONNULL_BEGIN
@interface ViewController : UIViewController
@property (nonatomic, copy, nullable) NSString *name;
@property (nonatomic, copy) NSString * __nullable title;
-(IBAction)clickFistViewController:(id)sender;
- (nonnull NSString *)testForSpecial:(NSString * __nullable)parameter;//注意两种用法,一个前,一个在后,后需要加 __
@end
NS_ASSUME_NONNULL_END
不过,为了安全起见,苹果还制定了几条规则:
1.typedef定义的类型的nullability特性通常依赖于上下文,即使是在Audited Regions中,也不能假定它为nonnull。
2.复杂的指针类型(如id *)必须显示去指定是nonnull还是nullable。例如,指定一个指向nullable对象的nonnull指针,可以使用”__nullable id * __nonnull”。我们经常使用的NSError **通常是被假定为一个指向nullable NSError对象的nullable指针。
4.兼容性
苹果已以帮我们处理好了这种兼容问题,我们可以安全地使用它们:
老代码仍然能正常工作, 即使对nonnull对象使用了nil也没有问题。
老代码在需要和swift混编时,在新的swift编译器下会给出一个警告。
nonnull不会影响性能。事实上,我们仍然可以在运行时去判断我们的对象是否为nil。