iOS9新特性学习
(一) 关键字
iOS9新出的关键字主要有nullable,nonnull,null_resettable,_Null_unspecified.用来修饰属性,或者方法的参数,方法的返回值 ,只能`修饰对象,不能修饰基本数据类型
-
属性中的关键字书写
-
nullable
的作用:表示可以为空 - 书写的规范:
-
//第一种写法
@property (nonatomic, strong, nullable) NSString *name;
//第二种写法
@property (nonatomic, strong) NSString *_Nullable name;
//第三种写法
@property (nonatomic, strong) NSString *__nullable name;
* `nonnull`的作用:表示不可以为空
* 书写的规范:
//第一种写法
@property (nonatomic, strong, nonnull) NSString *name;
//第二种写法
@property (nonatomic, strong) NSString *_Nonnull name;
//第三种写法
@property (nonatomic, strong) NSString *__nonnull name;
```
* 方法中的关键字书写:
- (nonnull NSString *)test:(nonnull NSString *)str;
- (NSString * _Nonnull)test1:(NSString * _Nonnull)str;
在宏 NS_ASSUME_NONNULL_BEGIN 和 NS_ASSUME_NONNULL_END之间定义的所有对象属性和方法默认都是nonnull
* `null_resettable`作用:get方法返回不能为空,set方法可以为空
* 如果使用该关键字修饰属性,需要重写get方法或者set方法,处理传递的值为空的情况
@property (nonatomic, strong, null_resettable) NSString *name;
* `_Null_unspecified`的作用:不确定是否为空
* 书写方式:
//第一种写法
@property (nonatomic, strong) NSString *_Null_unspecified name;
//第二种写法
@property (nonatomic, strong) NSString *__null_unspecified name;
### (二) 泛型
* 主要在集合(数组,字典,NSSet)中比较常见,当声明一个类,类里面的某些属性的类型不确定的时候,此时我们才使用泛型. 通过集合取出来对象,直接当做泛型对象使用,可以直接使用点语法
* 书写规范:在类型的后面定义泛型,如:NSMutableArray *datas,表明datas数组当中只能存放NSString类型的对象.如果向datas中添加非NSString类型的对象,编译器回报警告.
* 修饰:只能修饰方法的调用.
* 举个例子
新建一个类person类,Language类,都继承NSObject,再新建一个Java类和IOS类,都继承自Language.在person.h里面声明一个泛型
#import
#import "Language.h"
// 声明泛型
@interface Person : NSObject
// 语言
@property (nonatomic) ObjectType language;
- (ObjectType)language;
@end
```
在viewDidLoad方法中创建
Person *p = [[Person alloc] init]; //这种方式创建的泛型没有确定,类型为id类型
Person *iosP = [[Person alloc] init];//这种方式创建的泛型为IOS类型,代码提示会有明确的类型,比如
泛型的协变和逆变
- __covariant(协变):用于泛型数据强转类型,可以向上强转,子类可以转成 父类
- __contravariant(逆变):用于泛型数据强转类型,可以向下强转, 父类可以转成子类
例如:
Person *p = [[Person alloc] init];
Person *iosP = [[Person alloc] init];
//如果子类想给父类赋值
//此时编译器会报如警告
p = iosP;
此时只需在person.h中声明泛型的地方做一下修改即可
@interface Person<__covariant ObjectType> : NSObject
@end
```
//如果父类想给子类赋值:
iosP = p;
只需将__covariant修改为__contravariant即可
@interface Person<__contravariant ObjectType> : NSObject
@end
### (三) __kindof
* __kindof:表示当前类或者它子类
* __kindof书写格式: 放在类型前面,表示修饰这个类型,例如:(__kindof Person *)
* __kindof :在调用的时候,很清楚的知道返回类型
使用场景一 :
在person.h中声明几个方法
@interface Person : NSObject
//__kindof Person *:表示可以是Person类或者它的子类
- (__kindof Person *)person;
// 仅仅表示只能是Person类 - (Person *)person1;
// id坏处: 1.不能在编译的时候检查真实类型 2.返回值,没有提示 - (id)person2;
@end
新建一个student类,继承自Person类,在viewDidLoad方法里面创建一个student,在创建的过程中就可以看到提示信息的区别:
![](http://upload-images.jianshu.io/upload_images/1977955-ed2623bc9d075212.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
使用场景二: 开发过程中使用频率比较高的UITableView
原来的API方法:
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier;
基本每次都要强制类型转换一下.
新的API将其改为
- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;
既明确表明了返回值,又不必强转。