iOS The nullability qualifiers (为空性修饰符)

转自 http://www.jianshu.com/p/0aca839891fe

The nullability qualifiers 空特性 修饰符 是Xcode 6.3 引入的一种修饰符,主要用来修饰一个参数是否 可以为空, 用来 和 swift 过渡兼容。

在swift中,使用 !?来表示一个 optional 值是 non 还是 some, 表示 optional 值不为空, 表示 可能为空,可能不为空。 swift 中 ! ? 的用法 可以看这篇文章: Swift中的问号?和感叹号!

我们可以在 Xcode 的 发布说明里面看到相关的说明。

iOS The nullability qualifiers (为空性修饰符)_第1张图片
01_api输入框.png
iOS The nullability qualifiers (为空性修饰符)_第2张图片
02_侧边栏.png

nullability 为空性修饰符

The nullability qualifiers

在iOS9 中 Xcode 6.3 之后,Object-C 引入了 一种 为空性 修饰符,因此Objective-C 现在可以表示参数的 nullability 为空性。 修饰 属性 或者 变量。

为空性修饰符 中的 四种修饰符

  • nonnull 不为空
  • nullable 可以为空
  • null_unspecified 不确定是否为空
  • null_resettable setter 可以为空, getter 不为空

OC 中的为空性修饰符

在 OC 里面 我们使用 nonnullnullable 来表示 参数和属性 可以为空 或者 不可以为空。

例如,以下是 OC UITableView APIs 里面的一些 为空性 语句:

-(void)registerNib:(nonnull UINib *)nib forCellReuseIdentifier:
                   (nonnull NSString *)identifier;
-(nullable UITableViewCell *)cellForRowAtIndexPath:
                   (nonnull NSIndexPath)indexPath;
@property (nonatomic, readwrite, retain, nullable) UIView *backgroundView;

在 上面的方法参数里面。方法1 identifier 参数不能为空。 方法2 indexPath 参数不能为空。 属性 backgroundView 可以为空。

swift 中的为空性修饰符 ! ?

OC 中的为空性修饰符 与 swift中 optional类型数据的为空性相似。在 swift 中 使用 ? 表示 可以为空, 使用 ! 表示 不为空,

swift 中 对一个 optional 类型 使用 ! 不为空修饰 称为 implicitly-unwrapped optionals (隐式拆包optioanls) 。

swift 中的 non-optional 类似于 OC 的 nonnull-qualified types ,例如( UINib!)。

swift 中的 optional 类似于 OC 的 nullable-qualified types, 例如 ((e.g., UITableViewCell?))。

swift APIs 中 的 为空性 修饰 语句:

func registerNib(nib: UINib, forCellReuseIdentifier identifier: String)
func cellForRowAtIndexPath(indexPath: NSIndexPath) -> UITableViewCell?
var backgroundView: UIView?

在以上代码中, UIView 或许为空, UITableViewCell 或许为空

指针类型 与 为空性修饰符

为空性修饰符 可以修饰 所有的指针类型,包括 C指针类型,block 类型,以及C++ 指针类型, 为空性修饰符 修饰 指针类型时 使用双下划线,__nonnull __nullable

例如:在 C api 中 在block中的用法

void enumerateStrings(__nonnull CFStringRef (^ __nullable callback)(void));

callback 返回值 可以为空, CFStringRef函数 返回值不为空,在swift中这样使用

func enumerateStrings(callback: (() -> CFString)?)

三种不同类型的为空性修饰符

我们来总结以下, 为空性修饰符,一共有三种。

  1. 指针 使用 双下滑线 __nonnull nullable
  2. OC 中使用 nonnull nullable
  3. swift 中使用 ! ?
iOS The nullability qualifiers (为空性修饰符)_第3张图片
03_为空性修饰符.png
Type qualifier spelling Objective-C property/method spelling Swift view Meaning
__nonnull nonnull Non_optioanl,如 UINib 该值永远不会为nil(有一种例外是可能参数传递时传入的消息为空)
__nullable nullable Optional,如 UITAbleViewCell? 该值可能为nil
__null_unspecified null_unspecified 隐式拆包可选类型 如NSDate! 不确定该值是否为空(很少用)

不为空修饰宏

在OC中还提供了一个不为空修饰宏 NS_ASSUME_NONNULL_BEGNNS_ASSUME_NONNULL_END。 在接口中 nullable 的是少数,因此为了防止写一大堆 nonnull,Foundation 还提供了一对宏,包在宏里面的对象默认加 nonnull 不为空修饰符,只需要把 nullable 为空的指出来就行。

如下所示:

NS_ASSUME_NONNULL_BEGIN
// …
-(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier;
-(nullable UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath)indexPath;
@property (nonatomic, readwrite, retain, nullable) UIView *backgroundView;
// …
NS_ASSUME_NONNULL_END

在以上代码中 参数 nib、identifier、indexPath 虽然没有 添加 为空性修饰,但是在 不空空修饰宏中,因此 为 nonull。 backgroundView 为 nullable。

注意点:

  • typedef 定义的类型不会继承 nullability 特性, 而是根据上下文选择nullablenon-nullable ,所以,就算是在 宏内,typedef定义的类型也不会被当作nonnull。

null_resettable

null_resettable 是用来修饰 属性的, 被 null_resettable 修饰的属性, setter 返回值 修饰符为 nullablegetter 返回值 修饰符为 nonable. 也就是说 , setter 可以为空, getter 不能为空, (比如某些属性提供了默认值),此时使用 null_resettable 修饰属性 。
例如,UIViewtintColor 属性,当我们没有指定 填充色的时候,使用系统默认的填充色。

@property (nonatomic, retain, null_resettable) UIColor *tintColor;

此 属性变量在 swift API 中 为 隐式解包

var tintColor: UIColor!


文/Shumin_Wu(简书作者)
原文链接:http://www.jianshu.com/p/0aca839891fe
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

你可能感兴趣的:(iOS)