__在2015年的WWDC中,在Swift與OC混編的專題中,介紹了OC的新特性,雖然主要是為了Swift,但是對(duì)于喜歡OC的開發(fā)者來說,有新的特性總是好的.本文就以此介紹Objecitive-C在9.0后的三個(gè)主要特性牌废。
__
Nullability
泛型
__kindof
1.Nullability
Nullability用來標(biāo)記對(duì)象是否可以為空,只能用來修飾OC對(duì)象類型。
- nonnull聲明的屬性,顧名思義setter和getter方法都不能為空
// 可以在聲明的屬性類型后加__nonnull
@property (nonatomic, copy) NSString * __nonnull name;
// 還可以寫為
@property (nonnull, nonatomic, copy) NSString *name;
- nullable聲明的屬性, setter和getter方法都可為空
@property (nonatomic, copy) NSString *__nullable gender;
- null_resettable,setter方法可以為空,getter方法不能為空
@property (null_resettable, nonatomic, strong) NSArray *groups;
- 用null_resettable修飾屬性時(shí), 需在.m中重寫該屬性的setter方法
- (void)setGroups:(NSArray *)groups {
if (_groups == nil) {
_groups = [NSArray array];
return;
}
_groups = groups;
}
- 如果需要為每個(gè)屬性或者方法都指定nullable或nonnull是一件很麻煩的事,蘋果為了開發(fā)者的方便,定義了兩個(gè)宏NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END
NS_ASSUME_NONNULL_BEGIN
@interface UILabel (TouchEvent)
- (instancetype)initWithFrame:(CGRect)frame text:(NSString *)text target:(nullable id)target action:(nullable SEL)aciton;
@property (nullable, nonatomic, copy) NSString *name;
@end
NS_ASSUME_NONNULL_END
/*
在這兩個(gè)宏的代碼之間,針對(duì)所有屬性和方法添加了nonnull修飾, 我們只需要去指定nullable或者null_resettable的屬性
*/
2.泛型
限制了容器(數(shù)組, 集合, 字典)中存儲(chǔ)元素的類型,從數(shù)組中取出的元素變?yōu)槁暶鲿r(shí)的類型,不再是id類型.
// 數(shù)組中的元素類型為NSString
NSMutableArray<NSString *> *arr = [NSMutableArray array];
// 向數(shù)組中添加其他類型元素時(shí)會(huì)產(chǎn)生警告
[arr addObject:@20];
自定義泛型
// 新建一個(gè)Car類
// __covariant 協(xié)變性修飾 __covariant ObjectTape為泛型名
@interface Car<__covariant ObjectTape > : NSObject
// 可用ObjectTape聲明屬性
@property (nonatomic, strong) ObjectTape firstObject;
main.m
// 協(xié)變性 與 逆變性
Car *car1 = nil;
Car<NSArray *> *car2 = nil;
Car<NSMutableArray *> *car3 = nil;
// 大類型(任意類型) 可以給有泛型的賦值
// 有泛型的也可以給沒泛型的賦值
car1 = car2;
car1 = car3;
car2 = car1;
car3 = car1
__covariant 協(xié)變性 子類給父類賦值時(shí), 自動(dòng)強(qiáng)轉(zhuǎn)
__contravariant 逆變型 父類給子類賦值, 自行強(qiáng)轉(zhuǎn)(?)
3.__kindof
在方法的返回值中加__kindof修飾,返回值類型以及它的子類都可以接收這個(gè)返回值尼桶。拿系統(tǒng)的API來說明, 這個(gè)方法的返回值為UITableViewCell以及TableViewCell子類的實(shí)例,不再需要用id來接收节槐。
- (nullable __kindof UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;
在屬性聲明中,泛型與__kindof結(jié)合的用法,數(shù)組中能存Car類以及Car子類的對(duì)象
@property (nonatomic, strong) NSArray<__kindof Car *> *cars;