iOSiOS学习资料整理+学习方法程序员

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

2016-06-02  本文已影响1373人  zhanming

马上就要出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
{
    
}
Paste_Image.png

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

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

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方法:


get方法

set方法:

set方法

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

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

点语法

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

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

2.泛型:限制类型

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

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

表示数组里只能放UIButton对象

Paste_Image.png
泛型的好处

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

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

Paste_Image.png

DogOne,DogTwo,DogThree都继承于Dog

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

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

@property(nonatomic,strong)ObjectType  dog;

@end

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

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

Paste_Image.png

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

Paste_Image.png

协变(__covariant)和逆变 (__contravariant)

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

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

此时这样赋值会有警告

Paste_Image.png

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

@interface person<__covariant ObjectType> : NSObject

@property(nonatomic,strong)ObjectType  dog;

@end

这样就没有警告了

Paste_Image.png

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

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

@interface person<__contravariant ObjectType> : NSObject

@property(nonatomic,strong)ObjectType  dog;

@end

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

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

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

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

父类有这样一个类方法

@interface Dog : NSObject

+(instancetype)dog;

@end
Paste_Image.png

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

Paste_Image.png

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

@interface person<__contravariant ObjectType> : NSObject

+ (__kindof Dog*)dog;

@end
Paste_Image.png

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

上一篇下一篇

猜你喜欢

热点阅读