美文网首页
深度剖析nullable、__nullable、_Nullabl

深度剖析nullable、__nullable、_Nullabl

作者: LTOVE | 来源:发表于2018-08-13 20:16 被阅读0次

    背景介绍

    Swift 中,我们会使用 ?! 去显式声明一个对象或者方法的参数是optional 还是 non-optional ,而在 Objective-C 中则没有这一区分,这样就会带来一个问题:在 SwiftObjective-C 混编时,Swift编译器并不知道一个 Objective-C 对象或者一个方法的参数到底是 optional 还是 non-optional,因此这种情况下编译器会隐式地都当成是 non-optional 来处理,这显然是不太好的

    发展历程

    为了解决这个问题,苹果在 Xcode 6.3 引入了一个 Objective-C 的新特性: Nullability Annotations ,这一新特性的核心是两个新的类型修饰: __nullable__nonnull 。从字面上我们可知, __nullable 表示对象可以是 NULLnil,而__nonnull 表示对象不应该为空。当我们不遵循这一规则时,编译器就会给出警告。
    Xcode 7 中,为了避免与第三方库潜在的冲突(猜测),苹果把 __nonnull/__nullable改成 _Nonnull/_Nullable 。再加上苹果同样支持了没有下划线的写法 nonnull/nullable ,于是就造成现在有三种写法这样混乱的局面。但是这三种写法本质上都是互通的,只是放的位置不同

    null_resettable

    作用:setter可为空, gette不可为空

    应用实例

    方法返回值的修饰

    - (nullable NSString*)method;
    - (NSString* __nullable)method;
    - (NSString* _Nullable)method;
    

    声明属性的修饰

    @property (nonatomic,copy,nullable) NSString *aString;
    @property (nonatomic,copy) NSString* __nullable aString;
    @property (nonatomic,copy) NSString* _Nullable aString;
    

    方法参数的修饰

    - (void)methodWithString:(nullable NSString*)aString;
    - (void)methodWithString:(NSString* _Nullable)aString;
    - (void)methodWithString:(NSString* __nullable)aString;
    

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

    - (void)methodWithError:(NSError* _Nullable * _Nullable)error
    - (void)methodWithError:(NSError* __nullable* __null_unspecified)error;
    // 以及其他的组合方式
     
    - (void)methodWithBlock:(nullablevo id(^)())block;
    // 注意上面的 nullable 用于修饰方法传入的参数 Block 可以为空,而不是修饰 Block 返回值;
    - (void)methodWithBlock:(void(^ _Nullable)())block;
    - (void)methodWithBlock:(void(^ __nullable)())block;
     
    - (void)methodWithBlock:(nullableid__nonnull(^)(id__nullableparams))block;
    // 注意上面的 nullable 用于修饰方法传入的参数 Block 可以为空,而 __nonnull 用于修饰 Block 返回值 id 不能为空;
    - (void)methodWithBlock:(id__nonnull(^ __nullable)(id__nullableparams))block;
    - (void)methodWithBlock:(id_Nonnull (^ _Nullable)(id_Nullable params))block;
    // the method accepts a nullable block that returns a nonnull value
    // there are some more combinations here, you get the idea
    

    相关文章

      网友评论

          本文标题:深度剖析nullable、__nullable、_Nullabl

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