iOS编程

iOS-OC中nullable、_Nullable、__null

2021-04-22  本文已影响0人  Imkata

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

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

对于属性、方法返回值、方法参数的修饰,使用nullable/nonnull。

对于 C 函数的参数、Block 的参数、Block 返回值的修饰,使用:_Nullable/_Nonnull。

建议弃用__nullable/__nonnull。

//对于C函数的参数、Block的参数、Block返回值的修饰,使用:_Nullable/_Nonnull
typedef NSString * _Nullable (^ParamStrBlock)(NSString * _Nullable  paramStr);

@interface XUNullable ()

//对于属性、方法返回值、方法参数的修饰,使用nullable/nonnull
@property (nonatomic, strong, nullable) NSObject *obj;
@property (nonatomic, strong, nullable) ParamStrBlock block;

@end

@implementation XUNullable

//对于属性、方法返回值、方法参数的修饰,使用nullable/nonnull
- (nullable NSObject *)addObject:(nullable NSObject *)object block:(nullable ParamStrBlock)block {
    self.obj = object;
    return object;
}

@end

如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END。在这两个宏之间的代码,所有简单指针对象都被假定为nonnull,因此我们只需要去指定那些nullable的指针,对于基本数据类型,不能指定是否可以为空。

上一篇 下一篇

猜你喜欢

热点阅读