1.Nullability
添加了一些新的关键字.
关键字 |
作用描述 |
nonnull / __nonnull / _Nonnull |
不可为空 |
nullable / __nullable / _Nullable |
可以为空 nullable更多的作用在于程序员之间的沟通交流(提醒同事某个属性可能是nil) |
null_unspecified |
不确定是否可以为空(极少情况) |
null_resettable |
set方法可以为nil,get方法不可返回nil, |
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END |
二者之间的所有属性都是 __nonnull |
举例
@property (nonnull, copy, nonatomic) NSString *title;
@property (nullable, copy, nonatomic) NSString *authur;
@property (null_unspecified, copy, nonatomic) NSString *name;
@property (null_resettable, copy, nonatomic) NSString *age;
@property (nonatomic, strong, nullable) NSArray *names;
@property (nonatomic, strong) NSArray * __nullable ages;
// 错误写法
//@property (nonatomic, assign, nullable) int age;
// 在调用方法传nil的时候会有警告。
- (void)setValue:(NSNumber * _Nonnull )number{
}
- (void)setValue:(NSNumber * __nonnull )number{
}
- (void)setValue:(nonnull NSNumber * )number{
}
// NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END 之间的所有属性都是 __nonnull
NS_ASSUME_NONNULL_BEGIN
@interface ViewController ()
@property (nonatomic, strong) NSArray *a1;
@property (nonatomic, strong) NSArray *a2;
@property (nonatomic, strong) NSArray *a3;
@property (nonatomic, strong) NSArray *a4;
@property (nonatomic, strong) NSArray *a5;
@end
NS_ASSUME_NONNULL_END
2.泛型
用法
// 声明了这样一个数组后,就好比我告诉了编译器,这个数组中的数据类型都是NSString *类型的,如果我这个数组中元素的方法,会有提示了.
NSMutableArray<NSString *> *array = [[NSMutableArray alloc] init];
// 在我们向这个数组中追加元素的时候,编译器将元素的类型提示了出来,并且将FromArray方法中需要的元素类型也提示了出来。
// 同样如果我们向这个数组中追加类型不匹配的元素,会有警告。
自定泛型
// 这个Type其实只是一个类型标识符,它具体怎么写并不重要,只是系统中都约定使用了Type.
@interface Bag<Type> : NSObject
@property (strong, nonatomic) Type typeObj;
@property (nonatomic, strong, nonnull) NSMutableArray<Type> *array;
@property (nonatomic, strong, nonnull) NSMutableArray<UIView *> *viewArray;
@property (strong, nonatomic) NSMutableDictionary<NSString *, NSNumber *> *dict;
- (void)add:(nonnull Type)object;
- (Type)get:(int)index;
@end
协变性与逆变性
Bag<NSString *> *bagt1;
Bag<NSMutableString *> *bagt2;
bagt1 = bagt2; // 这里如果我们这样写,强行转换,会报警告,就有了逆变和协变这个概念
关键字 |
作用描述 |
__covariant |
子类型指针可以向父类型指针转换 |
__contravariant |
父类型指针可以向子类型转换 |
我们将自定义的类做如下修改,就不会出现警告了
@interface Bag<__covariant Type> : NSObject
@property (strong, nonatomic) Type typeObj;
@property (nonatomic, strong, nonnull) NSMutableArray<Type> *array;
@property (nonatomic, strong, nonnull) NSMutableArray<UIView *> *viewArray;
@property (strong, nonatomic) NSMutableDictionary<NSString *, NSNumber *> *dict;
- (void)add:(nonnull Type)object;
- (Type)get:(int)index;
@end
3._kindof
关键字 |
作用描述 |
__kindof |
告诉编译器,这里可以返回Type类型 的子类指针 |
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn;
Bag *bag = [[Bag alloc] init];
[bag.viewArray addObject:btn];
// 这里会有警告,说类型不对
UIButton *button = [bag.viewArray firstObject];
}
以前需要强转,现在只需要这样,加上__kindof
警告就没了
@property (nonatomic, strong, nonnull) NSMutableArray<__kindof UIView *> *viewArray;