深度剖析nullable、__nullable、_Nullable、_Nonnull、null_resettable

背景介绍

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

猜你喜欢

转载自blog.csdn.net/u014034079/article/details/81636303