iOS9新增的一些新特性
1.關(guān)鍵字
iOS9新出的關(guān)鍵字:用來修飾屬性,或者方法的參數(shù),方法的返回值
好處
1.迎合swift
2.提高開發(fā)人員的開發(fā)規(guī)范须妻,減少程序員之間的交流
iOS9新出的關(guān)鍵字nonnull,nullable只能修飾對象菇篡,不能修飾基本數(shù)據(jù)類型
nullable:表示可以為空
//nullable:表示可以為空
//兩種常用方式
@property(nonatomic,strong,nullable)NSString *nameStr1;
@property(nonatomic,strong)NSString *_Nullable nameStr2;
//nonnull: non:非 null:空
@property(nonatomic,strong,nonnull)NSString *icon1;
@property(nonatomic,strong)NSString *_Nonnull icon2;
//方法中關(guān)鍵字的書寫規(guī)范
-(nonnull NSString *)test1:(nonnull NSString *)str1;
-(NSString *_Nonnull)test2:(NSString *_Nonnull)str2;
對于上面的nonnull,新的Xcode里面的UIKit框架多了NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END兩個字段波闹,這兩句話的意思和nonnull一樣
在NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END之間酝豪,定義的所有屬性和方法默認都是nonnull,可以發(fā)現(xiàn)蘋果的對象都是這樣修飾的
NS_ASSUME_NONNULL_BEGIN
@property(nonatomic)NSString *nStr;
NS_ASSUME_NONNULL_END
除了上面的幾個修飾符精堕,有的對象還有null_resettable這個修飾符
/*
null_resettable: get方法不能返回為空孵淘, set方法可以為空
注意:如果使用null_resettable,必須重寫get方法
*/
@property(nonatomic,strong,null_resettable) NSString *testStr;
重寫get方法
//法一
-(NSString *)testStr{
if (_testStr ==nil) {
_testStr = @"重寫get方法 法1";
}
return _testStr;
}
//法2
-(void)setTestStr:(NSString *)testStr
{
if (testStr == nil) {
testStr = @"重寫get方法 法2";
}
_testStr = testStr;
}
_Null_unspecified:不確定是否為空
還有一個_Null_unspecified的修飾符歹篓,會在self.testStr的時候出現(xiàn)瘫证。用self.testStr的時候不確定是取值還是賦值,不確定是set還是get 沒什么意義
@property(nonatomic,strong) NSString *_Null_unspecified testStr1;
2.泛型
泛型: 限制類型
泛型使用場景
1.在集合(數(shù)組庄撮,字典背捌,NSSet)中使用泛型比較常見
2.當(dāng)聲明一個類,類里面的某些屬性類型不確定洞斯,這時我們才使用泛型
泛型書寫規(guī)范
在類型后面定義泛型毡庆,NSMutableArray<NSString *> *dataArr;
泛型修飾
只能修飾方法的調(diào)用
泛型好處
1.提高開發(fā)規(guī)范,減少程序員之間的交流
2.通過集合取出來的對象烙如,直接當(dāng)泛型對象使用么抗,可以直接使用.點語法
基本的使用 下面的例子表明這個數(shù)組是字符串類型
@property(strong,nonatomic)NSMutableArray<NSString*> *dataArr;
拓展
定義三個對象Person、Java亚铁、IOS
其中Java和IOS繼承自Language
Language和Persion都繼承自NSObject
#import <Foundation/Foundation.h>
#import "Language.h"
#import "IOS.h"
#import "Java.h"
//模仿NSMutableArray系統(tǒng)自帶
@interface Person<ObjectType> : NSObject
//語言
//@property(nonatomic) id language;
//@property(nonatomic) IOS *language;
@property(nonatomic) ObjectType language;
/*
id: 任何對象都能傳進來
Language: 在外面調(diào)用的時候蝇刀,沒有提示
IOS:外面調(diào)用只能傳對象
*/
//如果沒有<IOS *> 泛型就確定,就是id類型
Person<IOS *> *p = [[Person alloc] init];
p.language = [IOS new];
@end
泛型 協(xié)變和異變
協(xié)變
__covariant(協(xié)變):用于數(shù)據(jù)強制類型徘溢,可以向上強轉(zhuǎn)吞琐,子類可以轉(zhuǎn)成父類(NSArray點進去可以看到修飾符和NSMutableArray不一樣)
只需要在Persion中的ObjectType前面加上__covariant
@interface Person<__covariant ObjectType> : NSObject
然后在ViewController中調(diào)用的時候就可以使用了
Person<Language *> *p = [Person new];
Person<IOS *> *iosP = [[Person alloc] init];
iosP.language = [IOS new];
//如果子類想給父類賦值,協(xié)變
p = iosP;
逆變
__contravariant(逆變):用于泛型類型數(shù)據(jù)強制類型,可以向下強轉(zhuǎn)然爆,父類可以轉(zhuǎn)成子類
和協(xié)變類似站粟,Persion后的修飾詞改成__contravariant就是逆變
@interface Person<__contravariant ObjectType> : NSObject
Person<Language *> *p = [Person new];
Person<IOS *> *iosP = [[Person alloc] init];
iosP.language = [IOS new];
//逆變
iosP = p;
3.__kindof
點開UITableView里面,發(fā)現(xiàn)里面有__kindof的關(guān)鍵字
__kindof:表示當(dāng)前類或者它子類
__kindof書寫格式:
放在類型前面施蜜,表示修飾這個類型
__kindof:在調(diào)用的時候卒蘸,很清楚的知道返回的類型
同樣創(chuàng)建一個繼承自NSObject的Person類,Son類繼承自這個類
在Person類中寫方法
法1
.h
+(id)person;
.m
+(id)person{
return [[self alloc] init];
}
法2
僅僅表示Person類
.h
+(Person *)person;
.m
+(Person *)person{
return [[self alloc] init];
}
法3
會自動識別當(dāng)前類的調(diào)用
.h
+(instancetype)person;
.m
+(instancetype)person{
return [[self alloc] init];
}
法4
__kindof Person * 表示可以是Person類或者他的子類
.h
+(__kindof Person *)person;
.m
+(Person *)person{
return [[self alloc] init];
}
在ViewController中調(diào)用的時候,可以清晰的看出來[Son person]定義的對象的類型缸沃,可以是Person恰起,也可以是Son類型的
Son *s = [Son person];
id的壞處:1.不能在編譯的時候檢測真是類型 不能調(diào)用.點語法
2.返回值沒有提示
NSString *str = [Son person];