1.參考資料
《Effective Objective-C 2.0 編寫高質(zhì)量iOS與OS X代碼的52個(gè)有效方法》
http://blog.sunnyxx.com/2014/12/18/class-cluster/
2.知識(shí)點(diǎn)
1)創(chuàng)建類簇
typedef NS_ENUM(NSUInteger, EmployeeType) {
EmployeeType_Developer,
EmployeeType_Designer,
EmployeeType_Finance,
}
@interface Employee : NSObject
@property (copy) NSString *name;
@property NSUInteger salary;
+ (Employee *)employeeWithType:(EmployeeType);
+ (void)doWork;
@end
@implementation Employee
+ (Employee *)employeeWithType:(EmployeeType) {
switch (type) {
case EmployeeType_Developer:{
return [EmployeeDeveloper new];
break;
}
//...
}
}
- (void)doWork {
//Subclasses implement this function.
}
@end
基類根據(jù)不同的類型蹲堂,創(chuàng)建不同的類實(shí)例吩跋,而所有的類實(shí)例都是基類的子類筹误。這種“工廠模式”是創(chuàng)建類簇的辦法之一却桶。由于OC中沒有抽象類的概念衅檀,使用時(shí)要注意:不要?jiǎng)?chuàng)建基類實(shí)例(一般的做法是基類中不提供init方法)菇曲。大致的幾條規(guī)則:
- 子類應(yīng)該繼承自類簇中的“抽象基類”
- 子類應(yīng)該定義自己的數(shù)據(jù)存儲(chǔ)方式
- 子類應(yīng)當(dāng)覆寫基類文檔中指明需要覆寫的方法
2)從NSArray看類簇
id obj1 = [NSArray alloc]; // __NSPlacehodlerArray *
id obj2 = [NSMutableArray alloc]; // __NSPlacehodlerArray *
id obj3 = [obj1 init]; // __NSArrayI *
id obj4 = [obj2 init]; // __NSArrayM *
alloc方法先生成了__NSPlacehodlerArray中間對(duì)象神僵,這就是一個(gè)工廠類熊经。按照sunnyxx的猜測(cè)脏榆,內(nèi)部有可能是如下實(shí)現(xiàn)的:
static __NSPlacehodlerArray *GetPlaceholderForNSArray() {
static __NSPlacehodlerArray *instanceForNSArray;
if (!instanceForNSArray) {
instanceForNSArray = [[__NSPlacehodlerArray alloc] init];
}
return instanceForNSArray;
}
static __NSPlacehodlerArray *GetPlaceholderForNSMutableArray() {
static __NSPlacehodlerArray *instanceForNSMutableArray;
if (!instanceForNSMutableArray) {
instanceForNSMutableArray = [[__NSPlacehodlerArray alloc] init];
}
return instanceForNSMutableArray;
}
// NSArray實(shí)現(xiàn)
+ (id)alloc {
if (self == [NSArray class]) {
return GetPlaceholderForNSArray()
}
}
// NSMutableArray實(shí)現(xiàn)
+ (id)alloc {
if (self == [NSMutableArray class]) {
return GetPlaceholderForNSMutableArray()
}
}
// __NSPlacehodlerArray實(shí)現(xiàn)
- (id)init {
if (self == GetPlaceholderForNSArray()) {
self = [[__NSArrayI alloc] init];
}
else if (self == GetPlaceholderForNSMutableArray()) {
self = [[__NSArrayM alloc] init];
}
return self;
}
所以猖毫,只是單純的alloc一個(gè)NSArray,占用的內(nèi)存地址應(yīng)該是一樣的须喂。
id obj1 = [NSArray alloc];
id obj2 = [NSArray alloc];
id obj3 = [NSMutableArray alloc];
id obj4 = [NSMutableArray alloc];
// 1和2地址相同吁断,3和4地址相同典唇,無論多少次都相同,且地址相差16位