苹果在Xcode引入的一个Objective-C的新特性:nullability annotations。
在Swift中可以使用!和?来表示一个对象是optional(可选类型)还是non-optional(不可选类型),而在Objective-C中则没有这一区分。这样就会造成一个问题:在Swift与Objective-C混编时,Swift编译器并不知道一个Objective-C对象到底是optional还是non-optional,因此这种情况下编译器会隐式地将Objective-C的对象当成是non-optional。
引入nullability annotations一方面为了让iOS程序员平滑地从Objective-C过渡到Swift,另一方面也促使开发者在编写Objective-C代码时更加规范,减少同事之间的沟通成本。
区别
关键字 | 使用 | 修饰位置 |
---|---|---|
nonnull | 表示修饰的属性或参数不能为空 | 属性/方法参数/方法返回值 |
nullable | 表示修饰的属性或参数可以为空 | 属性/方法参数/方法返回值 |
null_resettable | 表示修饰的属性,get方法不能返回为空,set方法可以赋值为空 | 属性 |
null_unspecified | 表示修饰的属性或参数不确定是否为空 | 属性/方法参数/方法返回值 |
在属性中使用
- nonnull
@property (nonatomic, copy, nonnull) NSString *nameA;
@property (nonatomic, copy) NSString *_Nonnull nameB;
@property (nonatomic, copy) NSString *__nonnull nameC;
@property (nonatomic, strong, nonnull) NSNumber *age;
@property (nonatomic, assign, nonnull) int age;// 不可修饰基本数据类型
- nullable
@property (nonatomic, copy, nullable) NSString *nameA;
@property (nonatomic, copy) NSString *_Nullable nameB;
@property (nonatomic, copy) NSString *__nullable nameC;
- null_resettable
@property (nonatomic, copy, null_resettable) NSString *nameA;
- null_unspecified
@property (nonatomic, copy, null_unspecified) NSString *nameA;
@property (nonatomic, copy) NSString *_Null_unspecified nameB;
@property (nonatomic, copy) NSString *__null_unspecified nameC;
在方法参数、方法返回值中使用
- nonnull
- (nonnull NSString *)buyBookA:(nonnull NSString *)book;
- (NSString *_Nonnull)buyBookB:(NSString *_Nonnull)book;
- (NSString *__nonnull)bugBookC:(NSString *__nonnull)book;
- nullable
- (nullable NSString *)buyBookA:(nullable NSString *)book;
- (NSString *_Nullable)buyBookB:(NSString *_Nullable)book;
- (NSString *__nullable)bugBookC:(NSString *__nullable)book;
- null_resettable
null_resettable只能在属性中使用,方法中无法使用
- null_unspecified
- (null_unspecified NSString *)buyBookA:(null_unspecified NSString *)book;
- (NSString *_Null_unspecified)buyBookB:(NSString *_Null_unspecified)book;
- (NSString *__null_unspecified)bugBookC:(NSString *__null_unspecified)book;
拓展
苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END,这两个宏来统一给属性和方法参数和返回值加上nonnull修饰,NS_ASSUME_NONNULL_BEGIN 和 NS_ASSUME_NONNULL_END之间,定义的所有对象属性和方法默认都是nonnull
注意事项
- nonnull无下划线,_Nonnull一条下划线,__nonnull两条下划线
- 对于属性、方法参数、方法返回值的修饰,可以使用:nonnull 、nullable 或者 _Nonnull、_Nullable 或者 __nonnull、__nullable
- 对于 C函数的参数、Block的参数、Block返回值的修饰,只能使用: _Nonnull、_Nullable 或者 __nonnull、__nullable
- 苹果的API建议弃用__nonnull、__nullable
网友评论