nullable、nonnull、__nullable、__nonnull、_Nullable、__Nonnull 的区别
在苹果自己的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
、_Nullable
和 nonnull
、__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
。而且苹果也支持没有下划线的写法 nonnull
、nullable
,于是就三种写法都可以使用的情况。
从上面的代码可以看出, nullable
修饰于类型前, 但__nullable
和 _Nullable
却修饰于类型后。
那么它们还有其他的区别呢?
对于方法参数、方法返回值、属性的修饰,可以使用:nonnull
、nullable
或者 _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_BEGIN
和 NS_ASSUME_NONNULL_END
。在这两个宏之间的代码,所有简单指针对象都被认为是 nonnull
修饰的 ,所以我们只需要指定 nullable
的指针对象即可。
NS_ASSUME_NONNULL_BEGIN- (void)methodWithString4:(NSString *)str string:(nullable NSString *)string {}NS_ASSUME_NONNULL_END
如上写的话, 参数str
为 nonnull
的, 而参数string
为 nullable
的。
总结
对于方法参数、方法返回值、属性的修饰,可以使用:nonnull
、nullable
或者 _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 的区别相关推荐
- 深度剖析nullable、__nullable、_Nullable、_Nonnull、null_resettable
背景介绍 在 Swift 中,我们会使用 ? 和 ! 去显式声明一个对象或者方法的参数是optional 还是 non-optional ,而在 Objective-C 中则没有这一区分,这样就会带来 ...
- Objective-C中的nullable、__nullable、__Nullable
nullable.__nullable._Nullable 都表示对象可以是NULL或nil nonnull.__nonnull._Nonnull 都表示对象不应该为空 它们是Obective-C特性 ...
- iOS关键字之nullable、nonnull、null_resettable、_Null_unspecified的区别
nullable.nonnull.null_resettable._Null_unspecified是iOS9.0出现的新的修饰关键词,下面我们来研究一下它们之间的区别. 一 共同点 1.可以进行代码 ...
- java中的nullable_java – @NonNull和@Nullable的正确用法是什么?
我对这些注释的正确使用感到困惑. android.support.annotation.NonNull; android.support.annotation.Nullable; @NonNull文档 ...
- java nonnull_java – Objects :: nonNull和x – x!= null之间有什么区别吗?
考虑以下课程: import java.util.Objects; import java.util.function.Predicate; public class LambdaVsMethodRe ...
- java 使用nullable_java – @NonNull和@Nullable的正确用法是什么?
我对这些注释的正确使用感到困惑. android.support.annotation.NonNull; android.support.annotation.Nullable; @NonNull文档 ...
- 【iOS开发-AFNetWorking下的POST和GET】
文章目录 写在开头 GET 和POST GET 和POST的区别联系 AFNetWorking 使用方法 DEMO GET请求数据 GET方法 GET请求到的数据解析 POST请求 POST的请求测试 ...
- [iOS开发]AFNetworking源码学习
目录 简介 开始解读 核心类 AFURLSessionManger 作用 属性和接口方法 代理 AFURLSessionManagerTaskDelegate _AFURLSessionTaskSwi ...
- iOS9 iOS10 iOS11的新特性
iOS9 特性 关键字参考 2015 Objective-C 新特性 1.关键字 : 这些是纯编译器的语法支持(llvm 7.0),没有借助任何 objc runtime 的升级,也就是说,这个新语法 ...
最新文章
- 自动sqlldr脚本
- 本文将向您展示如何在 Flutter 中编码/解码 JSON
- vb.net获取服务器中所有数据库名称显示在list,vb listview显示数据库内容,该怎么解决...
- 八、Pandas的基本使用
- html 获取鼠标在canvas上的坐标,html5-canvas 检测鼠标在画布上的位置
- tidb时间转字符串_如何使用TiDB节省时间
- 让Windows CE 6.0 R2支持.NET CF 3.5
- c++ 传入字符串 带返回值_python的数据类型(三):字符串
- 菜鸟python_菜鸟爱Python第1期:Python发展史?对Python最深刻的解读
- ACL 2020投稿论文超3000篇,中国投稿量第一,录取率却未进前10
- 在Kubernetes上使用Sateful Set部署RabbitMQ集群
- 解决问题:vscode中文乱码(亲测有效)
- eclipse:STS下载使用(STS(Spring Tool Suite)其实是个被包装过的eclipse)
- android大智慧安装目录,大智慧文件目录
- 玩转windows XP
- When Machine Learning Meets Congestion Control: A Survey and Comparison
- Kile 2.1.3 发布,TeX/LaTeX 集成编辑器
- linux 互斥机制
- 关于Google账号被封、被下架、提审被拒等原因分析及建议
- 牛客练习赛66 E-骚区间
热门文章
- 图幅号计算(JS、HTML)
- 【实战】Serv-U MDTM Time Zone Exploit
- cpp初阶--Lesson 04 类和对象(下)
- 使用BeautifulSoup对头条收藏的HTML数据进行分析
- python画七彩圆圈_python内置库turtle绘制有趣图形
- 强力推荐一个学习coding的网站,怒赞!!
- 为什么我建议程序员用macbook
- 使用卷积神经网络处理猫狗识别数据集_v1
- 16免费人格测试软件,16personalities
- [iCloud]iCloud学习笔记--APP内启用iCloud及CloudKit Dashboard介绍