在苹果自己的API中, 我们也见过许多的参数的修饰符, 比如说在方法中修饰参数可否为空的标识。今天来总结下 nullable, nonnull, __nullable, __nonnull, _Nullable, __Nonnull 之间的区别。

作用

首先, nonnull, __nonnull, __Nonnull 这三个修饰的参数是不可以为nil的。如果参数被它们修饰, 且传入的实参为nil的话, 编译器将会产生警告。
nullable, __nullable, _Nullable 这三个修饰的参数是可以为nil的。如果参数被它们修饰, 且传入的实参为nil的话, 编译器也不会产生警告。

用法

// string 可以为 nil
- (void)methodWithString:(nullable NSString *)string {}
// string 不可以为 nil
- (void)methodWithString:(nonnull NSString *)string {}

nullable__nullable_Nullable 的区别联系

nullable__nullable_Nullablenonnull__nonnull__Nonnull 其实是成对的, 所以这里只介绍前者, 后者用法与前者一致。

先来看一段代码, 可以考虑下它们之间的区别是什么。

@property (nonatomic, copy, nullable) NSString *string1;
@property (nonatomic, copy) NSString * _Nullable string2;
@property (nonatomic, copy) NSString * __nullable string3;- (void)methodWithString1:(nullable NSString *)string {}
- (void)methodWithString2:(NSString * _Nullable)string {}
- (void)methodWithString3:(NSString * __nullable)string {}

其实呢, 这三种写法的效果都是一样的,只是代码摆放的位置不同。
苹果在 Xcode 6.3 引入了一个 Objective-C 的新特性: Nullability Annotations ,它的核心是两个修饰: __nullable__nonnull 。在 Xcode 7 中,为了避免与第三方库潜在的冲突,苹果把 __nonnull__nullable 改成 _Nonnull_Nullable 。而且苹果也支持没有下划线的写法 nonnullnullable ,于是就三种写法都可以使用的情况。

从上面的代码可以看出, nullable 修饰于类型前, 但__nullable_Nullable 却修饰于类型后。

那么它们还有其他的区别呢?
对于方法参数、方法返回值、属性的修饰,可以使用:nonnullnullable 或者 _Nonnull_Nullable 或者 __nonnull__nullable
对于 C函数的参数、Block的参数、Block返回值的修饰,只能使用: _Nonnull_Nullable 或者 __nonnull__nullable 。但是根据苹果的API来说建议弃用__nonnull__nullable

所以应该按照下面的代码来写:

// C函数
- (void)methodWithError1:(NSError * _Nullable * _Nullable)error {}
// Block 返回值
- (void)methodWithBlock1:(void(^ _Nullable)(void))block {}
- (void)methodWithBlock2:(void(^ __nullable)(void))block {}
// 注意下面的 nullable 用于修饰传入的参数 block 可以为空,而不是修饰 block 返回值
- (void)methodWithBlock3:(nullable void(^)(void))block {}
// Block返回值 和 Block参数
- (void)methodWithBlock4:(NSString * __nonnull(^ __nullable)(NSString * __nullable params))block {}
- (void)methodWithBlock5:(NSString * _Nonnull (^ _Nullable)(NSString * _Nullable params))block {}
// 注意下面的 nullable 用于修饰方法传入的参数 block 可以为空,而 __nonnull 用于修饰 block 返回值 NSString 不能为空;
- (void)methodWithBlock6:(nullable NSString * __nonnull(^)(NSString * __nullable params))block {}

拓展 Nonnull Audited Regions

有两个宏 NS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_END 。在这两个宏之间的代码,所有简单指针对象都被认为是 nonnull 修饰的 ,所以我们只需要指定 nullable 的指针对象即可。

NS_ASSUME_NONNULL_BEGIN- (void)methodWithString4:(NSString *)str string:(nullable NSString *)string {}NS_ASSUME_NONNULL_END

如上写的话, 参数strnonnull的, 而参数stringnullable 的。

总结

对于方法参数、方法返回值、属性的修饰,可以使用:nonnullnullable 或者 _Nonnull_Nullable 或者 __nonnull__nullable
对于 C函数的参数、Block的参数、Block返回值的修饰,只能使用: _Nonnull_Nullable 或者 __nonnull__nullable 。但是根据苹果的API来说建议弃用__nonnull__nullable

Demo下载地址:
Demo
参考资料:
Difference between nullable, __nullable and _Nullable in Objective-C

nullable、nonnull、__nullable、__nonnull、_Nullable、__Nonnull 的区别相关推荐

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

    背景介绍 在 Swift 中,我们会使用 ? 和 ! 去显式声明一个对象或者方法的参数是optional 还是 non-optional ,而在 Objective-C 中则没有这一区分,这样就会带来 ...

  2. Objective-C中的nullable、__nullable、__Nullable

    nullable.__nullable._Nullable 都表示对象可以是NULL或nil nonnull.__nonnull._Nonnull 都表示对象不应该为空 它们是Obective-C特性 ...

  3. iOS关键字之nullable、nonnull、null_resettable、_Null_unspecified的区别

    nullable.nonnull.null_resettable._Null_unspecified是iOS9.0出现的新的修饰关键词,下面我们来研究一下它们之间的区别. 一 共同点 1.可以进行代码 ...

  4. java中的nullable_java – @NonNull和@Nullable的正确用法是什么?

    我对这些注释的正确使用感到困惑. android.support.annotation.NonNull; android.support.annotation.Nullable; @NonNull文档 ...

  5. java nonnull_java – Objects :: nonNull和x – x!= null之间有什么区别吗?

    考虑以下课程: import java.util.Objects; import java.util.function.Predicate; public class LambdaVsMethodRe ...

  6. java 使用nullable_java – @NonNull和@Nullable的正确用法是什么?

    我对这些注释的正确使用感到困惑. android.support.annotation.NonNull; android.support.annotation.Nullable; @NonNull文档 ...

  7. 【iOS开发-AFNetWorking下的POST和GET】

    文章目录 写在开头 GET 和POST GET 和POST的区别联系 AFNetWorking 使用方法 DEMO GET请求数据 GET方法 GET请求到的数据解析 POST请求 POST的请求测试 ...

  8. [iOS开发]AFNetworking源码学习

    目录 简介 开始解读 核心类 AFURLSessionManger 作用 属性和接口方法 代理 AFURLSessionManagerTaskDelegate _AFURLSessionTaskSwi ...

  9. iOS9 iOS10 iOS11的新特性

    iOS9 特性 关键字参考 2015 Objective-C 新特性 1.关键字 : 这些是纯编译器的语法支持(llvm 7.0),没有借助任何 objc runtime 的升级,也就是说,这个新语法 ...

最新文章

  1. 自动sqlldr脚本
  2. 本文将向您展示如何在 Flutter 中编码/解码 JSON
  3. vb.net获取服务器中所有数据库名称显示在list,vb listview显示数据库内容,该怎么解决...
  4. 八、Pandas的基本使用
  5. html 获取鼠标在canvas上的坐标,html5-canvas 检测鼠标在画布上的位置
  6. tidb时间转字符串_如何使用TiDB节省时间
  7. 让Windows CE 6.0 R2支持.NET CF 3.5
  8. c++ 传入字符串 带返回值_python的数据类型(三):字符串
  9. 菜鸟python_菜鸟爱Python第1期:Python发展史?对Python最深刻的解读
  10. ACL 2020投稿论文超3000篇,中国投稿量第一,录取率却未进前10
  11. 在Kubernetes上使用Sateful Set部署RabbitMQ集群
  12. 解决问题:vscode中文乱码(亲测有效)
  13. eclipse:STS下载使用(STS(Spring Tool Suite)其实是个被包装过的eclipse)
  14. android大智慧安装目录,大智慧文件目录
  15. 玩转windows XP
  16. When Machine Learning Meets Congestion Control: A Survey and Comparison
  17. Kile 2.1.3 发布,TeX/LaTeX 集成编辑器
  18. linux 互斥机制
  19. 关于Google账号被封、被下架、提审被拒等原因分析及建议
  20. 牛客练习赛66 E-骚区间

热门文章

  1. 图幅号计算(JS、HTML)
  2. 【实战】Serv-U MDTM Time Zone Exploit
  3. cpp初阶--Lesson 04 类和对象(下)
  4. 使用BeautifulSoup对头条收藏的HTML数据进行分析
  5. python画七彩圆圈_python内置库turtle绘制有趣图形
  6. 强力推荐一个学习coding的网站,怒赞!!
  7. 为什么我建议程序员用macbook
  8. 使用卷积神经网络处理猫狗识别数据集_v1
  9. 16免费人格测试软件,16personalities
  10. [iCloud]iCloud学习笔记--APP内启用iCloud及CloudKit Dashboard介绍