美文网首页
iOS日记2-iOS中的类簇

iOS日记2-iOS中的类簇

作者: Mcyboy007 | 来源:发表于2017-02-08 19:32 被阅读0次

    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中的类簇

          本文链接:https://www.haomeiwen.com/subject/kuxmittx.html