几个新的关键字
__kindof
@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *subviews;
这个属性是UIKit库里UIView.h头文件中声明的,使用带有这个修饰符的属性作为右值时,不用强转就可以赋给左值了。
UIButton * button = self.view.subviews.lastObject ;
之前没有__kindof的时候,上面的写法编译器会报黄⚠️。
需要写成 UIButton * button = (UIButton *) self.view.subviews.lastObject ;
nullable
UITableView.h 头文件中 对 dataSource 和 delegate 这两个代理的声明如下
@property (nonatomic, weak, nullable) id <UITableViewDataSource> dataSource;
@property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;
null able 表示 可以没有,即TableView的这两个代理属性可以是没有的
nonnull
@property (nonatomic, strong, nonnull) Class * someInstance ;
这是一个测试的属性,用来nonnull 修饰符表示,someInstance 这个属性必须不为nil
可以在UITableView.h的一开始找到 NS_ASSUME_NONNULL_BEGIN
这个宏会默认把之后所有的对象默认都添加nonnull,除非手动添加了nullable。
泛型
@interface NSArray<__covariant ObjectType>:NSObject
上面的内容来自Foundation框架中的NSArray.h
定义了继承自NSObject的类,NSArray 其元素是ObjectType类型(__covariant后面再解释)
<ObjectType>就是泛型,用来限制NSArray元素的类型。
@property (nonatomic, strong) NSMutableArray<NSString *> * arr ;
声明了一个名字为arr的可变数组,其元素类型是NSString类型。
当arr中添加了不是字符串的类型 编译器会报黄⚠️。
泛型的协变 子类可以强转为父类的类型 关键字__covariant
@interface Test<__covariant ObjectType>:NSObject
Test<NSString *> * stringTest ;
Test<NSMutableString *> * mutableStringTest ;
stringTest = mutableStringTest ; 这样是可以赋值的,因为NSMutableString 是 NSString的子类
mutableStringTest = stringTest ; 这样编译器会⚠️
泛型的逆变 父类可以强转为子类的类型 关键字__contravariant
@interface Test<__contravariant ObjectType>:NSObject
Test<NSString *> * stringTest ;
Test<NSMutableString *> * mutableStringTest ;
stringTest = mutableStringTest ; 这样编译器会⚠️
mutableStringTest = stringTest ; 这样是可以赋值的,因为NSString是NSSMutableString的父类