面试题(Category)

  • 分类(Category)和扩展(Extension)有什么区别?
  • 分别用来做什么?
  • 分类的局限性?
  • 分类的结构体有哪些成员?

答案参考链接:Category VS Extension 原理详解

他们的作用:

Category

  • 可以减少单个文件的体积
  • 把不同功能组织到不同的Category里
  • 可以由多个开发者共同完成一个类
  • 可以按需加载想要的category
  • 声明私有方法
  • 模拟多继承(一定要搞懂多继承概念)
  • 把framework的私有方法公开(先了解framework)

Extension

  • Extension可以添加属性和方法,且方法必须实现
  • 隐藏私有信息

区别

  • extension在编译器决议,属于类的一部分,category在运行时决议
  • extension必须在有一个类的源码时才能添加,category不需要有类的源码
  • extension可以添加实例变量,category不可以

Category 结构体 category_t

struct category_t {
    const char *name;
    classref_t cls;
    struct method_list_t *instanceMethods; // 对象方法
    struct method_list_t *classMethods; // 类方法
    struct protocol_list_t *protocols; // 协议
    struct property_list_t *instanceProperties; // 属性
    // Fields below this point are not always present on disk.
    struct property_list_t *_classProperties;

    method_list_t *methodsForMeta(bool isMeta) {
        if (isMeta) return classMethods;
        else return instanceMethods;
    }

    property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
};

问: Category的实现原理,以及Category为什么只能加方法不能加属性?

答:分类的实现原理是将category中的方法,属性,协议数据放在category_t结构体中,然后将结构体内的方法列表拷贝到类对象的方法列表中。 Category可以添加属性,但是并不会自动生成成员变量及set/get方法。因为category_t结构体中并不存在成员变量。通过之前对对象的分析我们知道成员变量是存放在实例对象中的,并且编译的那一刻就已经决定好了。而分类是在运行时才去加载的。那么我们就无法再程序运行时将分类的成员变量中添加到实例对象的结构体中。因此分类中不可以添加成员变量。

问:Category中有load方法吗?load方法是什么时候调用的?load 方法能继承吗?

答:Category中有load方法,load方法在程序启动装载类信息的时候就会调用。load方法可以继承。调用子类的load方法之前,会先调用父类的load方法

问:load、initialize的区别,以及它们在category重写的时候的调用的次序。

答:区别在于调用方式和调用时刻 调用方式:load是根据函数地址直接调用,initialize是通过objc_msgSend调用 调用时刻:load是runtime加载类、分类的时候调用(只会调用1次),initialize是类第一次接收到消息的时候调用,每一个类只会initialize一次(父类的initialize方法可能会被调用多次)

调用顺序:先调用类的load方法,先编译那个类,就先调用load。在调用load之前会先调用父类的load方法。分类中load方法不会覆盖本类的load方法,先编译的分类优先调用load方法。initialize先初始化父类,之后再初始化子类。如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次),如果分类实现了+initialize,就覆盖类本身的+initialize调用。

作者:xx_cc
链接:https://juejin.im/post/5aef0a3b518825670f7bc0f3

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,612评论 8 265
  • OC语言基础 1.类与对象 类方法 OC的类方法只有2种:静态方法和实例方法两种 在OC中,只要方法声明在@int...
    奇异果好补阅读 4,348评论 0 11
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,142评论 1 32
  • 面向对象的三大特性:封装、继承、多态 OC内存管理 _strong 引用计数器来控制对象的生命周期。 _weak...
    运气不够技术凑阅读 1,135评论 0 10
  • 你平行世界,还好有你——陌生人。 或与你,擦肩而过;或与你,侃侃而谈。大千世界,会有一个,爱你的人等着你,去爱。 ...
    etme阅读 683评论 5 3