美文网首页iOS基础与进阶
Objective-C 中 nullable、__nullabl

Objective-C 中 nullable、__nullabl

作者: 跃文 | 来源:发表于2019-05-15 10:13 被阅读0次

    在OC中存在__nullable与之对应的__nonnull修饰符,苹果为了避免与第三方库潜在的冲突把 __nonnull/__nullable 改成 _Nonnull/_Nullable。同时苹果同样还支持没有下划线的写法 nonnull/nullable,这三种写法本质上都是互通的,只是放的位置不同,意义用途如下:

    属性 表示意义 用途 区别
    __nullable 、_Nullable、nullable 表示对象可以是 NULL 或 nil 方法返回值修饰、参数修饰、声明属性修饰 放置位置不同
    __nonnull、_Nonnull、nonnull 表示对象不应该为空 同上 同上

    使用示例:

    • 方法返回值修饰:
    - (nullable NSString *)function;
    - (NSString * __nullable) function;
    - (NSString * _Nullable) function;
    
    • 声明属性的修饰:
    @property (nonatomic, copy, nullable) NSString * param;
    @property (nonatomic, copy) NSString * __nullable param;
    @property (nonatomic, copy) NSString * _Nullable param;
    
    • 方法参数修饰:
    - (void)functionWithParam:(nullable NSString *) param;
    - (void)functionWithParam:(NSString * _Nullable) param;
    - (void)functionWithParam:(NSString * __nullable) param;
    

    而对于 双指针类型对象Block 的返回值Block 的参数 等,这时候就不能用 nonnull/nullable 修饰,只能用带下划线的 __nonnull/__nullable 或者 _Nonnull/_Nullable

    - (void)functionWithError:(NSError * _Nullable * _Nullable)error
    - (void)functionWithError:(NSError * __nullable * __null_unspecified)error;
    
    - (void)functionWithBlock:(nullable(整体修饰符位置-外界传入block是否可以为空) id __nonnull(返回修饰符位置-block返回值是否可以为空)  (^)(id __nullable(参数修饰符位置) params))block;
    // 上面的 nullable 用于修饰方法传入的参数 Block 可以为空,__nonnull 用于修饰 Block 返回值 id 不能为空;
    
    

    根据原生 iOS SDK 里 Foundation 和 UIKit 的头文件以及苹果的博文《Nullability and Objective-C》,总结如下使用规范:

    • 对于属性、方法返回值、方法参数的修饰,使用:nonnull/nullable
    • 对于 C 函数的参数、Block 的参数、Block 返回值的修饰,使用:_Nonnull/_Nullable建议弃用 __nonnull/__nullable

    Nonnull Audited Regions

    如果每个属性或每个方法都去指定 nonnullnullable,将是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_END。在这两个宏之间的代码,所有简单指针对象都被假定为 nonnull,因此我们只需要去指定那些 nullable指针对象即可。如下代码所示:

    NS_ASSUME_NONNULL_BEGIN
    @interface myClass ()
    @property (nonatomic, copy) NSString * param;
    - (id)functionWithParam:(nullable NSString *)param;
    @end
    NS_ASSUME_NONNULL_END
    

    在上面的代码中,param 属性默认是 nonnull 的,functionWithParam: 方法的返回值也是 nonnull,而方法的参数 str 被显式指定为 nullable

    为了安全起见,苹果还制定了以下几条规则:

    • 通过 typedef 定义的类型的 nullability 特性通常依赖于上下文,即使是在 Audited Regions 中,也不能假定它为 nonnull
    • 对于复杂的指针类型(如 id *)必须显式去指定是 nonnull 还是 nullable。例如,指定一个指向 nullable 对象的 nonnull 指针,可以使用 __nullable id * __nonnull
    • 我们经常使用的 NSError ** 通常是被假定为一个指向 nullable NSError 对象的nullable指针。

    相关文章

      网友评论

        本文标题:Objective-C 中 nullable、__nullabl

        本文链接:https://www.haomeiwen.com/subject/aiyuaqtx.html