iOS日记2-iOS中的类簇

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位

你可能感兴趣的:(iOS日记2-iOS中的类簇)