iOS开发中类簇的应用
来源:互联网 发布:kali linux渗透教程pdf 编辑:程序博客网 时间:2024/05/16 06:19
类簇(class cluster)是一种设计模式,在Foundation Framework中被广泛使用,举个简单的例子:
NSArray *arr = [NSArray arrayWithObjects:@"foo",@"bar", nil];NSLog(@"arr class:%@", [arr class]);// output: __NSArrayI显然
__NSArrayI
是一个私有类,来看看这个类的头文件。@interface __NSArrayI : NSArray { unsigned int _used;}//...
可以看出__NSArrayI
继承了NSArray
。为什么要这么设计呢?拿NSNumber来举个例子,我们都知道NSNumber可以存储多种类型的数字,如Int/Float/Double等等,一种方式是把NSNumber作为基类,然后分别去实现各自的子类,像这样:
初看起来也没什么问题,但如果子类很多,像这样:
这对使用者来说显然不够方便,得记住这么多类。如果使用类簇,问题就变得简单了,把Number作为抽象基类,子类各自实现存取方式,然后在基类中定义多个初始化方式,像这样:
现在只需要记住一个类就可以了。NSNumber
的初始化伪代码大概像这样:
- (id)initWithBool{ return [[__NSCFBoolean alloc]init];}- (id)initWithLong{ return [[__NSCFNumber alloc]init];}//...
在iOS项目中的应用
在开发app时经常会遇到表现和行为完全一样,但数据源不一样的情况。以花瓣app为例,同样是瀑布流,可能来自我喜欢的图片、某个画板下的图片、某个用户的图片等等。如果为每一种表现方式都新建一个Controller,并且使用这个Controller来初始化,那么就会遇到最开始提到的问题:子类太多,使用不便。这正好可以通过类簇来很方便地搞定。比如这样:
@implementation HBWaterfallViewController- (id)initWithLiked{ return [[HBLikedViewController alloc]init];}- (id)initWithBoardID:(NSInteger)boardID{ return [[HBBoardViewController alloc]initWithBoardID:boardID];}#pragma mark - 通用的方法- (PSUICollectionViewCell *)collectionView:(PSUICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ // ...}// ...#pragma mark - 每个子类需要实现的方法- (void)fetchMoreData{ NSAssert(NO, @"子类需要实现此方法");}
使用起来类似这样[[HBWaterfallViewController alloc]initWithBoardID:9527]
或[[HBWaterfallViewController alloc]initWithLiked]
。如果有新的DataSource,新加一个初始化方法即可,对于使用者来说,打开头文件,看下init开头的方法就行了。
再举个例子,现在很多应用需要同时兼顾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这里
alloc
时并没有返回TestView
类,而是根据系统版本返回TestViewIOS6
或TestViewIOS7
。* 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
小结
类簇的本质其实是抽象工厂,类簇也可以有多个基类,如NSArray
,NSMutableArray
, 后者就是继承的前者。它对一些「大同小异」的问题,往往会有不错的效果。
- iOS开发中类簇的应用
- 开发的iOS应用
- iOS开发 addChildViewController的应用
- IOS开发:CoreData的应用
- 如何开发一款好的IOS应用?
- 常见的iOS手机应用开发流程
- iOS 应用的 UI 开发资源
- IOS应用开发常用的一些控件
- SQLite的多线程应用与iOS开发
- iOS开发 应用启动速度的优化
- iOS开发网络应用的利器
- iOS开发之二维码的应用
- iOS应用插件开发的思路
- iOS开发:查看应用的运行内存
- ios开发 - UIImageView 的contentMode属性应用
- 开发使用 iBeacon 的 iOS 7 应用
- 用来开发IOS应用的Java工具包
- iOS 开发 NSDate的一些应用
- RHEL5.1系统内核版本2.6.18升级到内核版本2.6.30
- C语言全局变量的总结
- 使用OpenSessionInViewFilter解决懒加载问题
- OLTP和OLAP
- Android中几种延时执行的方法
- iOS开发中类簇的应用
- 解读关键字volatile(C语言面试题分析之一)
- ext2.0 表单验证
- wpf项目打开多个窗体在任务栏只有一个任务
- java的反射机制1
- K2工作流学习笔记
- android通过webview组件实现与js相互调用
- iOS: 通过performSelectorOnMainThread在不同线程中更新界面
- 从分布式数据库的CAP特性说起