iOS10马上来了,iOS9的新特性你知道了吗?

马上就要出iOS10了,但是还是有好多小伙伴不知道iOS9的新特性,这怎么能行呢,今天就要给不知道小伙伴讲一讲。

1.关键字

nullable:表示可以为空

书写规范

@property(nonatomic,strong,nullable)UIImageView * image;
@property(nonatomic,strong)UIImageView * _Nullable image;

nonnull:表示不可以为空

书写规范

@property(nonatomic,strong,nonnull)UIImageView * image;
@property(nonatomic,strong)UIImageView * _Nonnull image;

方法中的使用和属于一样

-(void)test:(nullable NSString*)str
{
    
}
iOS10马上来了,iOS9的新特性你知道了吗?_第1张图片
Paste_Image.png

注意nullable,nonnull只能修饰对象,不能修饰基本数据类型

但是有一个问题,随便点开一个控件的头文件,你发现有些属性和方法使用nullable,但是没发现有哪个方法和属性使用nonnull的啊,这是怎么回事
大家看这里

iOS10马上来了,iOS9的新特性你知道了吗?_第2张图片
Paste_Image.png

Paste_Image.png

NS_ASSUME_NONNULL_BEGIN
NS_ASSUME_NONNULL_END

有这样一对宏表达的意思是:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END之间的对象属性和方法在默认情况下都是nonnull的**

null_resettable

表示get方法不行为空,set方法可以为空
例如

@property(nonatomic,strong,null_resettable)UIImageView * image;

get方法:


iOS10马上来了,iOS9的新特性你知道了吗?_第3张图片
get方法

set方法:

iOS10马上来了,iOS9的新特性你知道了吗?_第4张图片
set方法

如果使用null_resettable的话,必须重写get或者set方法来处理设置的值为空的情况,原因上面说了,get方法不能为空。

但是你会发现当你用点语法时

iOS10马上来了,iOS9的新特性你知道了吗?_第5张图片
点语法

_Null_unspecified的意思是不确定是否为空

因为你用点语法是赋值还是取值是不确定的

2.泛型:限制类型

泛型的使用场景一:集合中(数组,字典,NSSet)

书写规范
@property(nonatomic,strong)NSMutableArray *array;

表示数组里只能放UIButton对象

iOS10马上来了,iOS9的新特性你知道了吗?_第6张图片
Paste_Image.png
泛型的好处
  • 提高开发规范,减少程序员的交流成本
  • 从集合中取出的对象可以直接使用点语法

泛型的使用场景二:自定义泛型

现在有一个人的类,人有一个狗的属性,狗呢有不同的品种,当创建一个人类的时候给人类的狗属性赋值,因为狗的类型不确定,这时候怎么办呢?

iOS10马上来了,iOS9的新特性你知道了吗?_第7张图片
Paste_Image.png

DogOne,DogTwo,DogThree都继承于Dog

person.h定义一个属性
只表示声明泛型

//只是在声明泛型
@interface person : NSObject

@property(nonatomic,strong)ObjectType  dog;

@end

    person *p1=[person new];
    
    p1.dog=[DogOne new];
    
    person *p2=[person new];
    
    p2.dog=[DogTwo new];

在定义person时,确定想要的泛型
这时候看下图,dog属性的类型就确定了

iOS10马上来了,iOS9的新特性你知道了吗?_第8张图片
Paste_Image.png

如果在定义person时没有确定泛型,那么默认类型就为id

iOS10马上来了,iOS9的新特性你知道了吗?_第9张图片
Paste_Image.png

协变(__covariant)和逆变 (__contravariant)

协变(__covariant):用于泛型数据强转类型,可以向上强转,子类可以转成父类

    person *p1=[person new];
   
    p1.dog=[Dog new];
    
    person *p2=[person new];
    
    p2.dog=[DogTwo new];
   
    p1=p2;

此时这样赋值会有警告

iOS10马上来了,iOS9的新特性你知道了吗?_第10张图片
Paste_Image.png

如果在声明泛型的时候加上__covariant

@interface person<__covariant ObjectType> : NSObject

@property(nonatomic,strong)ObjectType  dog;

@end

这样就没有警告了

iOS10马上来了,iOS9的新特性你知道了吗?_第11张图片
Paste_Image.png

如果理解了协变(__covariant),那么逆变 (__contravariant)也就很容易了

逆变 (__contravariant):用于泛型数据强转类型,可以向下强转,父类可以转成子类

@interface person<__contravariant ObjectType> : NSObject

@property(nonatomic,strong)ObjectType  dog;

@end

这样父类既可以赋值给子类了

    person *p1=[person new];
   
    p1.dog=[Dog new];
    
    person *p2=[person new];
    
    p2.dog=[DogTwo new];
   
    p2=p1;

3.__kindof:表示当前类或它的子类

Dog类是DogOne类的父类,我就拿它们俩举例子

父类有这样一个类方法

@interface Dog : NSObject

+(instancetype)dog;

@end
iOS10马上来了,iOS9的新特性你知道了吗?_第12张图片
Paste_Image.png

当DogTwo调用父类的dog方法时返回的类型是instancetype

iOS10马上来了,iOS9的新特性你知道了吗?_第13张图片
Paste_Image.png

我们不知道返回的是什么
如果在这么写

@interface person<__contravariant ObjectType> : NSObject

+ (__kindof Dog*)dog;

@end
iOS10马上来了,iOS9的新特性你知道了吗?_第14张图片
Paste_Image.png

如果感觉这篇文章对您有所帮助,顺手点个喜欢,谢谢啦

你可能感兴趣的:(iOS10马上来了,iOS9的新特性你知道了吗?)