__在2015年的WWDC中,在Swift与OC混编的专题中,介绍了OC的新特性,虽然主要是为了Swift,但是对于喜欢OC的开发者来说,有新的特性总是好的.本文就以此介绍Objecitive-C在9.0后的三个主要特性。
__
Nullability
泛型
__kindof
1.Nullability
Nullability用来标记对象是否可以为空,只能用来修饰OC对象类型。
- 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修饰属性时, 需在.m中重写该属性的setter方法
- (void)setGroups:(NSArray *)groups {
if (_groups == nil) {
_groups = [NSArray array];
return;
}
_groups = groups;
}
- 如果需要为每个属性或者方法都指定nullable或nonnull是一件很麻烦的事,苹果为了开发者的方便,定义了两个宏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
/*
在这两个宏的代码之间,针对所有属性和方法添加了nonnull修饰, 我们只需要去指定nullable或者null_resettable的属性
*/
2.泛型
限制了容器(数组, 集合, 字典)中存储元素的类型,从数组中取出的元素变为声明时的类型,不再是id类型.
// 数组中的元素类型为NSString
NSMutableArray<NSString *> *arr = [NSMutableArray array];
// 向数组中添加其他类型元素时会产生警告
[arr addObject:@20];
自定义泛型
// 新建一个Car类
// __covariant 协变性修饰 __covariant ObjectTape为泛型名
@interface Car<__covariant ObjectTape > : NSObject
// 可用ObjectTape声明属性
@property (nonatomic, strong) ObjectTape firstObject;
main.m
// 协变性 与 逆变性
Car *car1 = nil;
Car<NSArray *> *car2 = nil;
Car<NSMutableArray *> *car3 = nil;
// 大类型(任意类型) 可以给有泛型的赋值
// 有泛型的也可以给没泛型的赋值
car1 = car2;
car1 = car3;
car2 = car1;
car3 = car1
__covariant 协变性 子类给父类赋值时, 自动强转
__contravariant 逆变型 父类给子类赋值, 自行强转(?)
3.__kindof
在方法的返回值中加__kindof修饰,返回值类型以及它的子类都可以接收这个返回值。拿系统的API来说明, 这个方法的返回值为UITableViewCell以及TableViewCell子类的实例,不再需要用id来接收。
- (nullable __kindof UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;
在属性声明中,泛型与__kindof结合的用法,数组中能存Car类以及Car子类的对象
@property (nonatomic, strong) NSArray<__kindof Car *> *cars;