iOS 关键字 及 泛型的使用 和 协变、逆变

关键字

1、nullable 和 nonnull

nullable:表示可以为空
nonnull:表示非空

在属性中的书写规范:

// 方式1
@property (nonatomic, strong, nullable) NSString *name1;
@property (nonatomic, strong, nonnull) NSString *name1;

// 方式2
@property (nonatomic, strong) NSString * _Nullable name2;
@property (nonatomic, strong) NSString * _Nonnull name2;

// 方式3
@property (nonatomic, strong) NSString * __nullable name3;
@property (nonatomic, strong) NSString * __nonnull name3;

在方法中的书写规范:

- (NSString * _Nullable)text:( NSString * _Nullable)str;
- (nonnull NSString *)text1:(nonnull NSString *)str;

需要注意的是,这两个关键字只能修饰对象类型,不能修饰基本数据类型

系统还定义了两个宏:NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END
在这两个宏之间定义的所有对象属性方法默认都是nonnull

2、null_resettable

null_resettable:get方法返回不能为空,set方法参数可以为空

用来修饰属性,一旦使用,必须重写该属性的get方法或者set方法,处理传递值为空的情况

在属性中的书写规范:

@property (strong, nonatomic, null_resettable) NSString *str;

3、null_unspecified

null_unspecified不确定是否为空

在属性中的书写规范:

// 方式1
@property (strong, nonatomic) NSString * _Null_unspecified str;
// 方式2
@property (strong, nonatomic) NSString * __null_unspecified str;

泛型

泛型:用于限制类型,常用于数组,字典,集合中
职能修饰方法调用
好处:
1、减少程序员的交流
2、可以直接使用点语法

在属性中的书写规范:

@property (strong, nonatomic) NSMutableArray<NSString *> *arr;

自定义泛型

当声明一个类,类中的某些属性的类型不确定时,需要使用泛型。

用例子说明自定义泛型:

先创建一个语言类Language,再创建两个基于Language的语言类,分别是 iOSJava 如:

Language类

#import <UIKit/UIKit.h>
@interface Language : NSObject
@end

iOS类

#import "Language.h"
@interface iOS : Language
@end

Java类

#import "Language.h"
@interface Java : Language
@end

创建Person类 如:

#import <Foundation/Foundation.h>
@interface Person<ObjectType> : NSObject
@property (nonatomic, strong)ObjectType language;
@end

只列出以上类的.h文件,.m文件没有添加方法和属性

在控制器的viewDidLoad 方法中:

- (void)viewDidLoad {
    [super viewDidLoad];
    Person<iOS *> *p1 = [[Person alloc] init];
    p1.language = [[iOS alloc] init];

    Person<Java *> *p2 = [[Person alloc] init];
    p2.language = [[Java alloc] init];
}

Person<iOS *> *p1 这样写,创建p1对象的language属性就只能是iOS类的对象,同理,p2对象的language属性就只能是Java类的对象。

协变,异变

__covariant 协变 用于 泛型 的数据类型强转,可以向上强转,子类 可以转成 父类

例如:
修改Person.h,在ObjectType前添加__covariant

#import <Foundation/Foundation.h>
@interface Person<__covariant ObjectType> : NSObject
@property (nonatomic, strong)ObjectType language;
@end

在控制器的viewDidLoad 方法中:

- (void)viewDidLoad {
    [super viewDidLoad];
    Person<Language *> *p = [[Person alloc] init];
    Person<iOS *> *iOSP = [[Person alloc] init];
    p.language = [[iOS alloc] init];

    // 如果子类想给父类赋值,用到协变
    p = iOSP;
}
__contravariant:逆变 用于 泛型 的数据类型强转,可以向下强转,父类 可以转成 子类

例如:
修改Person.h,在ObjectType前添加__contravariant

#import <Foundation/Foundation.h>
@interface Person<__contravariant ObjectType> : NSObject
@property (nonatomic, strong)ObjectType language;
@end

在控制器的viewDidLoad 方法中:

- (void)viewDidLoad {
    [super viewDidLoad];

    Person<Language *> *p = [[Person alloc] init];
    p.language = [[Java alloc] init];
    Person<iOS *> *iOSP = [[Person alloc] init];
    p.language = [[iOS alloc] init];

    // 如果父类想给子类赋值,用到逆变
    iOSP = p;

}

转载请注明出处,万分感谢!

猜你喜欢

转载自blog.csdn.net/qcx321/article/details/74002283
今日推荐