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位
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,467评论 30 472
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 5,899评论 0 9
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,242评论 19 139
  • 为什么很多内置类如UITableView的delegate属性都是assign而不是retain? 所有的引用计数...
    烟雨平生花飞舞阅读 4,937评论 0 3
  • 冬天一到,大家都喜欢吃火锅。因为火锅有个好处就是可以顾及多人的口味,而且它可以让男女老少、亲朋好友同桌、同锅。围着...
    河笑看海阅读 2,962评论 2 1

友情链接更多精彩内容