iOS 关键字和泛型

一.关键字

1.NS_ASSUME_NONNULL_BEGIN 和 NS_ASSUME_NONNULL_END

NS_ASSUME_NONNULL_BEGIN
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *address;
NS_ASSUME_NONNULL_END

NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END包裹的属性代表这些属性是非空的,如果传入空值,系统会有警告。


屏幕快照 2018-06-07 下午4.01.28.png

2.null_resettable

@property (nonatomic,copy,null_resettable) NSString *name;

null_resettable关键字修饰的属性 Getter方法的返回值不可以为空 但是Setter方法可以为空,并且如果使用null_resettable修饰属性,必须重写属性的Getter 或者 Setter方法处理值为空的情况。否则会出现如下警告:


屏幕快照 2018-06-07 下午4.21.04.png

在Getter方法中处理值为空的情况(Setter中处理也行)

- (NSString *)name {
    if (!_name) {
        _name = @"默认值";
    }
    return _name;
}
_Null_unspecified表明属性不确定是否为空.png

二.OC中泛型

1.自定义泛型

新建一个Person类
#import 
@interface Person : NSObject
@property (nonatomic,strong) ObjectType skill;
@end
调用【已经提前定义了IosProgramming和JavaProgramming两个类 代表ios编程和java编程】
    //如果不指定泛型  skill的setter类型为id类型 传入任何值均可
    Person *persion = [[Person alloc] init];
    persion.skill = @"测试";
    //指定泛型为IosProgramming 则skill的setter方法只可以传IosProgramming类的对象
    Person *persion = [[Person alloc] init];
    persion.skill = [IosProgramming new];
    //指定泛型为JavaProgramming 则skill的setter方法只可以传JavaProgramming类的对象
    Person *persion = [[Person alloc] init];
    persion.skill = [JavaProgramming new];

2.__covariant(协变)、__contravariant(逆变)

__covariant(协变):用于泛型中的强转类型,表明泛型可以向上强转,子类可以转成父类。
__contravariant(逆变):用于泛型中的强转类型,表明泛型可以向下强转,父类可以转成子类。

新建一个Person类
#import 
@interface Person : NSObject
@property (nonatomic,strong) ObjectType skill;
@end

新建Language、IOS类,Language是IOS的父类
Language类
#import 
@interface Language : NSObject
@end
IOS类
#import "Language.h"
@interface IOS : Language
@end

1.运行下列代码【子类转父类】:
    Person *p_language = [Person new];
    Person *p_ios = [Person new];
    //将p_ios赋值给p_language系统会发出类型不一致的警告
    p_language = p_ios;
解决办法:
指定Person的泛型为协变的:
#import 
@interface Person<__covariant ObjectType> : NSObject
@property (nonatomic,strong) ObjectType skill;
@end

2.运行下列代码【父类转子类】:
    Person *p_language = [Person new];
    Person *p_ios = [Person new];
    //将p_language赋值给p_ios系统会发出类型不一致的警告
    p_ios = p_language;
解决办法:
指定Person的泛型为逆变的:
#import 
@interface Person<__contravariant ObjectType> : NSObject
@property (nonatomic,strong) ObjectType skill;
@end

3.__kindof

__kindof 表明返回值类型是当前类或者当前类的子类。
定义一个Person和Son类,Person是Son的子类。在Person中定义一个类方法,用于快速创建Person对象。
id修饰返回值类型

定义类方法
#import 
@interface Person : NSObject
+ (id)person;
@end
编译下列代码,并没有提示类型错误。
NSString *son = [Person person];
1.用id修饰返回值类型,不会在编译时进行类型判断。
2.返回值类型没有确切提示。

Person修饰返回值类型

定义类方法
#import 
@interface Person : NSObject
+ (Person *)person;
@end
编译下列代码,提示类型不一致。
Son *son = [Son person];
1.用类名修饰返回值类型,子类调用父类的方法,不会自动识别类型。

instancetype修改返回值类型

定义类方法
#import 
@interface Person : NSObject
+ (Person *)person;
@end
编译下列代码,类型不一致的警告消除。
Son *son = [Son person];
1.虽然会自动识别当前对象的类,但是仍然没有类型提示。

__kindof Person * 修饰返回值类型

定义类方法
#import 
@interface Person : NSObject
+ (__kindof Person *)person;
@end
编译下列代码,此时不仅会自动识别当前对象的类,而且也会有类型提示。
Son *son = [Son person];

你可能感兴趣的:(iOS 关键字和泛型)