馬上就要出iOS10了,但是還是有好多小伙伴不知道iOS9的新特性,這怎么能行呢,今天就要給不知道小伙伴講一講。
1.關(guān)鍵字
nullable:表示可以為空
書(shū)寫規(guī)范
@property(nonatomic,strong,nullable)UIImageView * image;
@property(nonatomic,strong)UIImageView * _Nullable image;
nonnull:表示不可以為空
書(shū)寫規(guī)范
@property(nonatomic,strong,nonnull)UIImageView * image;
@property(nonatomic,strong)UIImageView * _Nonnull image;
方法中的使用和屬于一樣
-(void)test:(nullable NSString*)str
{
}

注意nullable,nonnull只能修飾對(duì)象,不能修飾基本數(shù)據(jù)類型
但是有一個(gè)問(wèn)題,隨便點(diǎn)開(kāi)一個(gè)控件的頭文件,你發(fā)現(xiàn)有些屬性和方法使用nullable,但是沒(méi)發(fā)現(xiàn)有哪個(gè)方法和屬性使用nonnull的啊,這是怎么回事
大家看這里


NS_ASSUME_NONNULL_BEGIN
NS_ASSUME_NONNULL_END
有這樣一對(duì)宏表達(dá)的意思是:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END之間的對(duì)象屬性和方法在默認(rèn)情況下都是nonnull的**
null_resettable
表示get方法不行為空,set方法可以為空
例如
@property(nonatomic,strong,null_resettable)UIImageView * image;
get方法:

set方法:

如果使用null_resettable的話,必須重寫get或者set方法來(lái)處理設(shè)置的值為空的情況,原因上面說(shuō)了,get方法不能為空。
但是你會(huì)發(fā)現(xiàn)當(dāng)你用點(diǎn)語(yǔ)法時(shí)

_Null_unspecified的意思是不確定是否為空
因?yàn)槟阌命c(diǎn)語(yǔ)法是賦值還是取值是不確定的
2.泛型:限制類型
泛型的使用場(chǎng)景一:集合中(數(shù)組,字典,NSSet)
書(shū)寫規(guī)范
@property(nonatomic,strong)NSMutableArray <UIButton *>*array;
表示數(shù)組里只能放UIButton對(duì)象

泛型的好處
- 提高開(kāi)發(fā)規(guī)范,減少程序員的交流成本
- 從集合中取出的對(duì)象可以直接使用點(diǎn)語(yǔ)法
泛型的使用場(chǎng)景二:自定義泛型
現(xiàn)在有一個(gè)人的類,人有一個(gè)狗的屬性,狗呢有不同的品種,當(dāng)創(chuàng)建一個(gè)人類的時(shí)候給人類的狗屬性賦值,因?yàn)楣返念愋筒淮_定,這時(shí)候怎么辦呢?

DogOne,DogTwo,DogThree都繼承于Dog
person.h定義一個(gè)屬性
<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時(shí),確定想要的泛型
這時(shí)候看下圖,dog屬性的類型就確定了

如果在定義person時(shí)沒(méi)有確定泛型,那么默認(rèn)類型就為id

協(xié)變(__covariant)和逆變 (__contravariant)
協(xié)變(__covariant):用于泛型數(shù)據(jù)強(qiáng)轉(zhuǎn)類型,可以向上強(qiáng)轉(zhuǎn),子類可以轉(zhuǎn)成父類
person <Dog*>*p1=[person new];
p1.dog=[Dog new];
person <DogTwo*>*p2=[person new];
p2.dog=[DogTwo new];
p1=p2;
此時(shí)這樣賦值會(huì)有警告

如果在聲明泛型的時(shí)候加上__covariant
@interface person<__covariant ObjectType> : NSObject
@property(nonatomic,strong)ObjectType dog;
@end
這樣就沒(méi)有警告了

如果理解了協(xié)變(__covariant),那么逆變 (__contravariant)也就很容易了
逆變 (__contravariant):用于泛型數(shù)據(jù)強(qiáng)轉(zhuǎn)類型,可以向下強(qiáng)轉(zhuǎn),父類可以轉(zhuǎn)成子類
@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:表示當(dāng)前類或它的子類
Dog類是DogOne類的父類,我就拿它們倆舉例子
父類有這樣一個(gè)類方法
@interface Dog : NSObject
+(instancetype)dog;
@end

當(dāng)DogTwo調(diào)用父類的dog方法時(shí)返回的類型是instancetype

我們不知道返回的是什么
如果在這么寫
@interface person<__contravariant ObjectType> : NSObject
+ (__kindof Dog*)dog;
@end

如果感覺(jué)這篇文章對(duì)您有所幫助,順手點(diǎn)個(gè)喜歡,謝謝啦