iOS9新特性学习

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;
既明确表明了返回值,又不必强转。

你可能感兴趣的:(iOS9新特性学习)