- 作用:修饰变量是否可以为空!
- 意义:和Swift中可选类型对接,提醒程序员做空判断,提高代码的严谨性!
nullable 、_Nullable、__nullable 被修饰者可空
nonnull 、_Nonnull 、__nonnull 被修饰者不能为空
- 区别: 使用时位置不同,绝大多数情况
nullable、nonnull
修饰时放在TYPE
前、带有下划线的__nonnull/_Nonnull ...
放TYPE
后 - 为了提高兼容性避免和第三方库潜在的冲突,苹果弃用
用__nonnull/_Nonnull
_Nonnull/_Nullable
替代
示列:
- 方法返回值修饰:
- (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 的参数 、C函数的参数等,这时候就不能用 nonnull/nullable
修饰,只能用带下划线的 __nonnull/__nullable
或者 _Nonnull/_Nullable
- 修饰双指针类型
- (void)methodWithError:(NSError * _Nullable * _Nullable)error
- (void)methodWithError:(NSError * __nullable * __nullable)error
- 修饰block对象
- (void)methodWithBlock:(nullable void (^)())block;
- (void)methodWithBlock:(void (^ _Nullable)())block;
- (void)methodWithBlock:(void (^ __nullable)())block;
- 修饰block返回值
- (void)methodWithBlock:(id __nonnull (^)())block;
- (void)methodWithBlock:(id _Nonnull (^)())block;
- 修饰block参数
- (void)methodWithBlock:(void (^ _Nullable)())block;
- (void)methodWithBlock:(void (^ __nullable)())block;
- 修饰block综合使用
- (void)methodWithBlock:(nullable id __nonnull (^)(id __nullable params))block;
- (void)methodWithBlock:(id __nonnull (^ __nullable)(id __nullable params))block;
- (void)methodWithBlock:(id _Nonnull (^ _Nullable)(id _Nullable params))block;
- 修饰C函数参数
int UIApplicationMain(int argc,
char * _Nullable argv[_Nonnull],
NSString * _Nullable principalClassName,
NSString * _Nullable delegateClassName);
- 对于复杂的指针类型(如
id *
)必须显式去指定是nonnull
还是 nullable。例如,指定一个指向nullable
对象的nonnull
指针,可以使用__nullable id * __nonnull
;
总结
使用规范:
-
对于属性、方法返回值、方法参数的修饰,使用:
nonnull/nullable
-
对于 C 函数的参数、Block 的参数、Block 返回值的修饰,使用:
_Nonnull/_Nullable
,建议弃用__nonnull/__nullable。
苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN
和 NS_ASSUME_NONNULL_END
。在这两个宏之间的代码,所有简单指针对象都被假定为 nonnull
,因此我们只需要去指定那些 nullable
指针对象即可。如下代码所示:
NS_ASSUME_NONNULL_BEGIN
@interface TestClass ()
- (void)methodWithParam:(nullable id)Param;
@end
NS_ASSUME_NONNULL_END
网友评论