iOS的一些关键字
最近在使用Swift的过程中,感觉到苹果公司为了迎合Swift,在Objective-C中添加了许多关键字。这些关键字一般用来用来修饰属性,或者方法的参数以及方法的返回值等等。而在以前的Objective-C开发中我们可能并不会去关注这样的一些关键字。尽管iOS10就要出了,但出于更深入了解两种语言的目的,我总结了一些Objective-C的新关键字。
新关键字的出现总是有其意义的,而iOS9的这些关键字可以很清晰的看出苹果公司推出的意义:
1.迎合Swift
因为Objective-C是一个弱类型的语言,程序在运行时才会去确认每个对象的类型与声明的类型是否一致。而Swift是强类型的语言,需要我们在编译时确定每一个对象的类型。这样两种语言在处理同一个方法或属性的时候可能会出现矛盾。为了迎合Swift,苹果公司添加了许多语言来兼容两种语言。
2.提高我们开发人员的开发规范,减少程序员之间的交流
我们以前可能没有规定全面一个属性的所有方面的需求,这样在遇到实际的需求的时候两个程序员对同一个接口的参数可能有歧义,不清楚是否可以为空等等。规定全面了这些问题后,我们在敏捷开发中就可以省去这部分不必要的交流,更多的时间与精力放在编程中。
一.nullable
这个关键字由两部分组成,与接下来的很多关键字是相同的。null:空的;able:可以。也就是说,nullable修饰的属性是可以为空的。
nullable有三种不同的书写规范,分别放在不同的位置,但表达的意思是相同的。
// 方式一:
@property (nonatomic, strong, nullable) NSString *nullableName; // 方式二:放在*号之后
@property (nonatomic, strong) NSString * _Nullable _NullableName; // 方式三:beta版本的关键字,手写的时候已经没有提示了
@property (nonatomic, strong) NSString * __nullable __nullableName;
简单来说,1.不带下划线的全小写nullable,放在括号内;2.带一个下划线的首字母大写_Nullable,放在星号*后;3.带两个下划线的全小写__nullable,放在星号*后。
之后的许多关键字都有这三种写法。不再一一赘述。
我们在调用的时候,系统会从最基本的提示变更为带有_Nullable可以为空提示的字样:
这样,我们是可以给这个属性设置为空的:
[self setName:nil];
既然一开始我们就提到了这些关键字是为了迎合Swift,那这个关键字体现在Swift中是什么呢?那就是 "?" 这个标识符了。这个标识符在Swift中代表这个常量/变量是可能为空的,对应到Objective-C中,自然就是nullable。
二.nonnull
non:非,不;null:空的。nonnull:非空的。也就是说,nonnull修饰的属性与上面nullable不同,是不能为空的。
nonnull同样有三种不同的书写格式:
方式一: @property (nonatomic, strong, nonnull) NSString *nonnullIcon; 方式二:放在*号之后 @property (nonatomic, strong) NSString * _Nonnull _NonnullIcon; 方式三:beta版本的关键字,已经没有提示 @property (nonatomic, strong) NSString * __nonnull __nonnullIcon;
与上面类似,不再赘述。
使用时,也与nullable有相似的效果:
我们在给标识为nonnull的属性设置为空时,系统会提示我们出错:
Warning:Null passed to a callee that requires a non-null argument. // callee:传话者,被召者,这里指代属性; argument:参数。
警告:我们将一个空值传给了一个要求非空参数的属性。
同样的,nonnull对应在Swift中,就是 "!" 标识符了,代表非空的。
三.注意:iOS9.0新出的关键字只能修饰对象,不能修饰基本数据类型
我们刚才试验的对象,都是字符串对象,NSString类型。那么我们可不可以用上述关键字修饰基本数据类型呢?我们可以试一下。
提示报错。
Alert:Nullability specifier 'nonnull' cannot be applied to non-pointer type 'int'. // specifier:分类符; applied:应用的,实用的
警告:表示非空的标识符"nonnull"不能适用于非指针类型'int'。
也就是说,新推出的关键字,只能修饰对象,不能修饰基本数据类型。
我们刚才都是在属性中使用关键字。而文章一开头就说明了,这些关键字除了用来修饰属性之外,还可以修饰方法的参数与返回值。那么这样是如何使用呢?
使用方式有两种,并不像之前的三种了:
- (nullable NSString *)test:(nullable NSString *)str;
- (NSString *_Nullable)test1;
而在调用过程中是这样的:
这样,我们一眼就能看明白这个参数或返回值是可以为空或非空的,就不会给他传空等等造成沟通的麻烦,也就体现了我之前提到的,减少不必要的交流的问题。
我们学习了nullable和nonnull之后,会发现我们几乎碰到所有系统类的属性与方法中都带着这两个之一的关键字。那么苹果官方是怎么写的呢?难道一个属性一个属性的添加这样的关键字吗?我们点进去UIButton,发现很多属性都带有nullable,而几乎看不到nonnull关键字。难道这些关键字都可以为空吗?
其实并不是这样。在许多类中,我们都会在开头和结尾看到这样两个宏的出现:
#define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") // assume:确认
#define NS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
在NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END两个宏之间,定义的所有对象属性和方法默认为nonnull。
我们可以尝试一下:
NS_ASSUME_NONNULL_BEGIN @property (nonatomic, strong) NSString *name; NS_ASSUME_NONNULL_END
这样,在调用这个属性的时候我们会发现:
[self setName:<#(NSString * _Nonnull)#>];
这个属性是默认非空的。
也就是说,我们也可以在我们的类中的开头和结尾使用这两个宏,然后我们只需要给可能为空的属性添加nullable就可以了。
六.null_resettable
null:空的; resettable:可重调; null_resettable:可以重新设置为空的。
这个关键字表示,这个属性getter方法不能返回为空;setter可以为空。如何会出现这种情况呢?也就是说,我们必须要重写这个属性的getter方法或setter方法来处理传值为空的情况,否则就会出现警告。
Warning:Synthesized setter 'setNull_resettableName:' for null_resettable property 'null_resettableName' does not handle nil.
警告:同步setter方法'setNull_resettableName:' 给可以设置为空的属性'null_resettableName'时没有经过处理。
这种典型的,就是我们在调ViewController的view时,系统将view的getter方法给重写了。大致是这样的:
@synthesize view = _view; - (UIView *)view { if (!_view) { [self loadView];
[self viewDidLoad];
} return _view;
}
同样的,我们也可以用同样的方式对null_resettable的属性进行处理:
@synthesize null_resettableName = _null_resettableName;
// 重写get
- (NSString *)null_resettableName { if (!_null_resettableName) { _null_resettableName = @"";
} return _null_resettableName;
} - (void)setNull_resettableName:(NSString *)null_resettableName { if (!null_resettableName) { _null_resettableName = @"";
} _null_resettableName = null_resettableName;
}
因为我同时重写了setter与getter方法,所以编译器需要找到属性null_resettableName的变量形式是什么。实际编程中,我们重写这两个方法中的任意一个就可以了。
七.null_unspecified
null:空的; unspecified:未特别指出的;未具体说明的; 也就是说null_unspecified是我们未具体指出是否为空,也就是默认状态。或者说,这个关键字写不写都行。
与之类似的,它有三种书写方式:
@property (nonatomic, strong, null_unspecified) NSString *null_unspecifiedName;
@property (nonatomic, strong) NSString *_Null_unspecified _Null_unspecifiedName;
@property (nonatomic, strong) NSString * __null_unspecified __null_unspecifiedName;
调用时,是这样的:
[self setNull_unspecifiedName:<#(NSString * _Null_unspecified)#>];
[self set_Null_unspecifiedName:<#(NSString * _Null_unspecified)#>];
[self set__nullableName:<#(NSString * _Nullable)#>];
希望大家有所收获。
iOS的一些关键字的更多相关文章
- iOS中__block 关键字的底层实现原理
在 <iOS面试题集锦(附答案)> 中有这样一道题目: 在block内如何修改block外部变量?(38题)答案如下: 默认情况下,在block中访问的外部变量是复制过去的,即:写操作不对 ...
- iOS 声明属性关键字的总结
atomic: 原子操作(原子性是指事务的一个完整操作,操作成功就提交,反之就回滚. 原子操作就是指具有原子性的操作)在objective-c 属性设置里面 默认的就是atomic ,意思就是 set ...
- IOS开发之关键字synchronized
static Config * instance = nil; +(Config *) Instance { @synchronized(self) { if(nil == instance) { ...
- iOS 声明属性关键字讲解
atomic: 原子操作(原子性是指事务的一个完整操作,操作成功就提交,反之就回滚. 原子操作就是指具有原子性的操作)在objective-c 属性设置里面 默认的就是atomic ,意思就是 set ...
- 【iOS】copy 关键字
以前没注意过 iOS 的 copy, nonatomic, assign, weak, strong 等关键字. 偏偏今天遇到了一个问题,恰恰是关键字的问题,如图: 之前用的是 assign, 没有用 ...
- iOS 新特性关键字
1.用来修饰属性,或者方法的参数,方法的返回值 /** nullable:表示可以传空 */ //@property (nonatomic, strong, nullable) NSString *n ...
- iOS Regex匹配关键字并修改颜色
引入第三方框架RegexKitLite /** * 根据传入的文字返回一个符合规则的富文本 * * @param title 匹配的文字 * * @return 创建的富文本 */ -(NSAttri ...
- ios开发static关键字的理解
:static关键字修饰局部变量::当static关键字修饰局部变量时,该局部变量只会初始化一次,在系统中只有一份内存 :static关键字不可以改变局部变量的作用域,但是可延长局部变量的生命周期,该 ...
- IOS开发 static关键字的作用
(1)函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次, 因此其值在下次调用时仍维持上次的值: (2)在模块内的 static 全局变量可以被模块内所 ...
随机推荐
- Python基础知识学习_Day1
1,python介绍 诞生于1989年圣诞节,目前越来越受到业界认可.应用领域十分广泛 云计算: 云计算最火的语言, 典型应用OpenStack WEB开发: 众多优秀的WEB框架,众多大型网站均为P ...
- tomcat解压版安装(摘自网络)
配置Tomcat[解压版] 选择解压版的Tomcat的理由是可以让我们使用多个Tomcat,但是配置上就会出现一些问题,需要我们手动进行更改配置.我的Tomcat版本是:apache-tomcat-6 ...
- 用微软makecert.exe生成一个自签名的证书
RT makecert.exe不用去找,安装VS2008后,在开始菜单相应的路径找到该命令提示符:Microsoft Visual Studio 2008/Visual Studio Tools/Vi ...
- Flashbuilder 破解方式 4.6 +4.7(网络资源整理)
Fb4.6 破解方式 安装完成后在安装目录下依次修改下列3个文件: (1).eclipse\plugins\com.adobe.flexbuilder.project_4.6.0.328916\MET ...
- 关于scanf()函数的一点理解
习惯了c++的cin.cout之后,也不怎么关注空格,反正cin.cout会自动处理.有一次实验,创建Huffman树,要求输入空格字符,当时就懵逼了.cin咋输入空格呢? 没办法,只能重新用scan ...
- JSON中JObject和JArray,JValue序列化(Linq)
http://blog.csdn.net/lovegonghui/article/details/50293629 一.JObject和JArray序列化 1.实例化JArray和JObject,然后 ...
- Oracle Day09 存储与触发器
1.存储 存储过程.存储函数:指存储在数据库中供所有用户程序调用的子程序. --创建存储过程(procedure) --用create procedure 命令建立存储过程. 格式: create o ...
- Hiver 操作 MySQL 导致锁表
Hadoop 搬迁到新集群后,操作主库 MySQL 导致了锁表...sad 具体锁表时间点 : 2016-1-14 14:31 到 2016-1-14 14:36 之间 在 oradba 的 ...
- swift UILabel加载html源码
@IBOutlet weak var content: UILabel! func setup(content:String){ self.content.preferredMaxLayoutWidt ...
- zookeeper 安装 windows环境
1.zookeeper下载地址: http://mirrors.cnnic.cn/apache/zookeeper/ 2.单点配置 把下载的zookeeper的文件解压到指定目录 修改conf下增加一 ...