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

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


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

set方法:

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

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

泛型的好處
- 提高開發(fā)規(guī)范,減少程序員的交流成本
- 從集合中取出的對象可以直接使用點(diǎn)語法
泛型的使用場景二:自定義泛型
現(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í)沒有確定泛型,那么默認(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í)這樣賦值會有警告

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

如果理解了協(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

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