IOS 類簇
類簇(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可以存儲多種類型的數(shù)字,如Int/Float/Double等等框沟,一種方式是把NSNumber作為基類拾碌,然后分別去實現(xiàn)各自的子類,比如所float街望,int校翔,double
初看起來也沒什么問題,但如果子類很多灾前,這對使用者來說顯然不夠方便防症,得記住這么多類。如果使用類簇哎甲,問題就變得簡單了蔫敲,把Number作為抽象基類,子類各自實現(xiàn)存取方式炭玫,然后在基類中定義多個初始化方式奈嘿,像這樣:
現(xiàn)在只需要記住一個類就可以了。NSNumber的初始化偽代碼大概像這樣:
- (id)initWithBool
{
return [[__NSCFBoolean alloc]init];
}
- (id)initWithLong
{
return [[__NSCFNumber alloc]init];
}
也可以想這樣子
- (id)initWithType:(Type)type
{
case:type
{
return [xxx new];
}
break;
case:type
{
return [xxx new];
}
break;
}
這樣做的好處就是在基類中不必做過多的判斷吞加,公共的方法可以寫在基類中裙犹,而不同的方法可以寫在各自的類中,這樣做可以使代碼更加的清晰衔憨。
在iOS項目中的應用現(xiàn)在很多應用需要同時兼顧不同的系統(tǒng)版本叶圃,在表現(xiàn)上需要為不同的系統(tǒng)加載不同的圖片資源,最簡單粗暴的方法就是各種if/else判斷践图,像這樣:
if ([[UIDevice currentDevice]systemMajorVersion] < 7)
{
/* iOS 6 and previous versions */
}
else
{
/* iOS 7 and above */
}
不夠優(yōu)雅掺冠,可以使用類簇的思想來去掉if/else判斷,把跟視圖具體元素無關的代碼放在基類码党,跟系統(tǒng)版本相關的代碼拆成兩個子類德崭,然后在各自的類中加載相應的資源。
/* 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類揖盘,而是根據(jù)系統(tǒng)版本返回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