个性化阅读
专注于IT技术分析

Objective-C泛型介绍和用法 – Objective-C开发教程

上一章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"];

以上是一种简单的泛型定义,另外我们还可以限制泛型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则是相反的意思,将泛型中的父类转为子类。

赞(1)
未经允许不得转载:srcmini » Objective-C泛型介绍和用法 – Objective-C开发教程

评论 抢沙发

评论前必须登录!