1.参考资料
《Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法》
http://blog.sunnyxx.com/2014/12/18/class-cluster/
2.知识点
1)创建类簇
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
基类根据不同的类型,创建不同的类实例,而所有的类实例都是基类的子类。这种“工厂模式”是创建类簇的办法之一。由于OC中没有抽象类的概念,使用时要注意:不要创建基类实例(一般的做法是基类中不提供init方法)。大致的几条规则:
- 子类应该继承自类簇中的“抽象基类”
- 子类应该定义自己的数据存储方式
- 子类应当覆写基类文档中指明需要覆写的方法
2)从NSArray看类簇
id obj1 = [NSArray alloc]; // __NSPlacehodlerArray *
id obj2 = [NSMutableArray alloc]; // __NSPlacehodlerArray *
id obj3 = [obj1 init]; // __NSArrayI *
id obj4 = [obj2 init]; // __NSArrayM *
alloc方法先生成了__NSPlacehodlerArray中间对象,这就是一个工厂类。按照sunnyxx的猜测,内部有可能是如下实现的:
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实现
+ (id)alloc {
if (self == [NSArray class]) {
return GetPlaceholderForNSArray()
}
}
// NSMutableArray实现
+ (id)alloc {
if (self == [NSMutableArray class]) {
return GetPlaceholderForNSMutableArray()
}
}
// __NSPlacehodlerArray实现
- (id)init {
if (self == GetPlaceholderForNSArray()) {
self = [[__NSArrayI alloc] init];
}
else if (self == GetPlaceholderForNSMutableArray()) {
self = [[__NSArrayM alloc] init];
}
return self;
}
所以,只是单纯的alloc一个NSArray,占用的内存地址应该是一样的。
id obj1 = [NSArray alloc];
id obj2 = [NSArray alloc];
id obj3 = [NSMutableArray alloc];
id obj4 = [NSMutableArray alloc];
// 1和2地址相同,3和4地址相同,无论多少次都相同,且地址相差16位