Objective-C,类簇详解Foundation框架中的类簇

来源:互联网 发布:网络发展前景 编辑:程序博客网 时间:2024/06/07 09:28

类簇(class cluster)是一种设计模式,在Foundation Framework中被广泛使用

1,类簇基本概念和介绍

百度百科中类簇的解释:http://baike.baidu.com/link?url=2BPwd028NVmCchel18RFT_Bhdzj4ZunUGNgM_wQE83alAlRog4P3Z_qOEtF52Oamp-bNY4zvP7lnu6_FdGkCEK

类簇:就是定义相同接口并提供相同功能的一组类的集合。 仅公开接口的抽象类也称为类簇的公共类。具体类的接口被公共类的接口抽象化,并被隐藏在簇的内部,具体类不能被直接使用,一般作为公共类的子类来实现,也被称为私有子类。

编写代码的时候,公共类和普通的类按照同样的方式使用,但是实际上被生成并放在内存上的是隐藏在类簇中某个类的实例。因为总能被正确执行,所以程序几乎意识不到什么差异。

实现某个类的方法并不是一成不变的,有些时候最合适的方法,在其它情况下可能深就意味着高成本。类簇有一个机制就是可以从已存在的私有类中挑选出最合适的方法去执行。

2,类簇的理解

1,当重写父类的初始化方法的时候,为什么要写 self = [super init] 呢,[super init] 就可以完成初始化父类部分了,为什么还要赋值给self呢,这是考虑到类簇的为题,如果创建的类是一个类簇比如NSString,这时候调用[super init]返回的对象可能并不是NSString,而是NSString的子类,这时候必须赋值给self不然返回的对象没有指针指向它,会发生内存泄露,如果不这么处理,程序中可能会出现各种各样奇怪的错误。


2,不要用自定义的类继承类簇

不要自定义继承自类簇的类,会出现各种意想不到的问题。

类簇内部的实现逻辑大概是:

+(id) alloc {  if ([self isEquals:[NSString class]]) {    return [NSPlaceholderString alloc];  } else {    return [super alloc];  }
如果自定义继承自类簇的类初始化alloc的时候,会返回自定义类的对象而不是NSString类型的对象,这时候就无法使用自定义类型的类去调用NSString类中的各种方法。否则会报错,找不到响相应的方法。

3,为什么要使用类簇

比如NSSnumber是一个类簇,如果不使用类簇的话,需要为每一种基本类型都提供一种封装,这样会使类的数量极其庞大,程序员需要记住大量的类,但是如果使用类簇的话,只需要记住NSNumber这一个类就行了,具体使用这个类返回的是设么类型的对象,会在NSNumber类内部做处理和判断,这样省去了很多的麻烦。


如果使用类簇,问题就变得简单了,把Number作为抽象基类,子类各自实现存取方式,然后在基类中定义多个初始化方式,现在只需要记住一个类就可以了。

类簇在项目中的使用:

现在很多应用需要同时兼顾iOS6和iOS7,在表现上需要为不同的系统加载不同的图片资源,最简单粗暴的方法就是各种if/else判断,像这样:

if ([[UIDevice currentDevice]systemMajorVersion] < 7){    /* iOS 6 and previous versions */}else{    /* iOS 7 and above */}
不够优雅,可以使用类簇的思想来去掉if/else判断,把跟视图具体元素无关的代码放在基类,跟系统版本相关的代码拆成两个子类,然后在各自的类中加载相应的资源。

/* TestView.h */@interface TestView: UIView/* Common method */- ( void )test;@end/* TestView.m */@implementation TestView+ (id)alloc{    if ([self class]== [TestView class])    {        if ([[UIDevice currentDevice] systemMajorVersion] < 7)        {            return [TestViewIOS6 alloc];        }        else        {            return [TestViewIOS7 alloc];        }    }    else    {        return [super alloc];    }}- ( void )test{}@end
<pre name="code" class="objc">/* TestViewIOS6.m */@implementation TestViewIOS6: TestView- (void)drawRect: (CGRect)rect{    /* Custom iOS6 drawing code */}@end/* TestViewIOS7.m */@implementation TestViewIOS7- (void)drawRect: (CGRect)rect{    /* Custom iOS7 drawing code */}@end



4,编程时候注意事项



参考文章:

1)http://baike.baidu.com/link?url=2BPwd028NVmCchel18RFT_Bhdzj4ZunUGNgM_wQE83alAlRog4P3Z_qOEtF52Oamp-bNY4zvP7lnu6_FdGkCEK

2)http://blog.csdn.net/itianyi/article/details/41350255 

3)http://limboy.me/ios/2014/01/04/class-cluster.html 

4)http://www.tuicool.com/articles/YJFvMnb 

5)《Objective-C编程全解(第三版)》




0 0