首先先认识两个特性:
__nullable 和 __nonnull,从字面上看, __nullable表示对象可以是 NULL 或 nil,而 __nonnull 表示对象不能为空,当我们不遵守这一规则时,编译器就会警告(⚠️)
事实上,在任何可以使用 const 关键字的地方都可以使用 __nullable 和 __nonnull,不过这两个关键字仅限于使用在指针类型上,
其实是为了配合 swift 使用出现的,因为 swift有可选类型,在Swift与Objective-C混编时,Swift编译器并不知道一个Objective-C对象到底是optional还是non-optional,因此这种情况下编译器会隐式地将Objective-C的对象当成是non-optional。
例如:
@property (nonatomic,strong) NSArray *__nonnull items;
现在回来我们要学习的 NS_ASSUME_NONNULL_BEGIN 和 NS_ASSUME_NONNULL_END,
如果每个地方都需要使用 nonnull 和 nonalbel,那么写起来会很繁琐,苹果为了减轻我们的工作,专门定义了两个宏NS_ASSUME_NONNULL_BEGIN 和 NS_ASSUME_NONNULL_END,会默认实现 ,
不过,为了安全起见,苹果还制定了几条规则:
1,typedef定义的类型的nullability特性通常依赖于上下文,即使是在Audited Regions中,也不能假定它为nonnull。
2,复杂的指针类型(如id *)必须显示去指定是nonnull还是nullable。例如,指定一个指向nullable对象的nonnull指针,可以使用”__nullable id * __nonnull”。
3,我们经常使用的NSError **通常是被假定为一个指向nullable NSError对象的nullable指针。
网友评论