上一章Objective-C开发教程请查看:Objective-C Foundation框架全解
泛型是比较有用的,泛型类似于万能指针id,以及void*。特别是在设计数据结构和算法的时候,如果你学过数据结构都知道,任意数据结构必定包含数据项,如果要提供以后复用,那就不好将这个数据项的数据类型写死了,使用泛型就可以将其定为任意类型,对于任意类型的数据都能使用该数据结构了。
OC中的NSArray和NSDictionary就是基于这个想法,容纳所有类型,可以使用NSObject、id指针、void*指针,而泛型除了能容纳指定的类型,还可以进行类型检查,在调用的时候指定数据类型,让代码更清晰。
泛型的定义和使用对某个类提供一个泛型声明,最简单的是使用以下语法:
@interface List<
T> : NSObject
@property(nonatomic, copy)T t;
-(instancetype)initWith: (T)t;
@end
注意这里的泛型T相当于id,它是一个指针,也是一个类型,在声明文件中涉及到T的都可以使用T类型声明,但是在实现文件中就不能再使用T了,要将对应的T类型变为id类型(实在有点麻烦),如下:
@implementation List
-(instancetype)initWith: (id)t{
if(self = [super self]){
_t = t;
}
return self;
}
@end
下面是使用示例:
List<
NSString> *list = nil;
list = [[List alloc]initWith: @"Hola"];
【Objective-C泛型介绍和用法 – Objective-C开发教程】以上是一种简单的泛型定义,另外我们还可以限制泛型T继承指定的类,传入的类可以是父类或父类的子类,如下:
@interface List<
T : NSObject*> : NSObject
@end
注意继承父类使用的是指针。泛型中不能指定T遵循的协议,不过也没办法,OC中的协议和Java的接口不同。而且要注意添加泛型定义是在类名和父类之间添加< T>,若要实现某个协议,则在父类后面添加< Protocol>,例如:
@interface List<
T : NSObject*> : NSObject <
NSCopying>
@end
再次体现了OC的语法繁杂——
协变和逆变:__covariant & __contravariant协变是使用__covariant关键字,什么意思呢?如果A是B的父类,将A类型传入一个泛型中,并进行赋值,如下:
List<
B> *b = [[List alloc]initWith: @"AA"];
List<
A> *a = b;
以上会产生警告,消除警告则可以使用__covariant关键字修饰泛型T,如下:
@interface List<
__covariant T> : NSObject
@end
__covariant修饰的T,表示当需要将子类转为父类的时候,如上面的b中的B类转为a中的A父类,也就允许将子类转为父类。
__contravariant则是相反的意思,将泛型中的父类转为子类。
推荐阅读
- Objective-C快速枚举用法 – Objective-C开发教程
- Objective-C Foundation框架全解 – Objective-C开发教程
- Objective-C复合对象解析 – Objective-C开发教程
- Objective-C类型检查和动态绑定详解 – Objective-C开发教程
- Objective-C协议(Protocol)用法解析 – Objective-C开发教程
- Objective-C扩展(Extension)用法解析 – Objective-C开发教程
- Objective-C冒充posing用法解析 – Objective-C开发教程
- Objective-C类别(Category)用法解析 – Objective-C开发教程
- Objective-C类设计和数据封装 – Objective-C开发教程