Category

Category结构如下(Category编译之后的底层结构是struct category_t,存储着分类的对象方法、类方法、属性、协议信息):

程序运行是runtime会将Category中的数据合并到类和元类对象中(如实例方法在类对象,类方法在元类中)

1.Category和Extension的区别是什么?

  • 主要区别是Extension在编译的时候合并数据
  • Category在运行是合并数据
  • 其他就是一些常用 展示私有方法,扩展等

2.Category加载过程?

  • 把先编译的Category数据(方法、属性、协议)加载到原来类数据前面(如加入数据前),后面编译的Category在数组前,会优先调用(后编译,先调用)
  • 源码解读顺序


     

3.load方法?调用顺序?

  • +load()在runtime加载类,分类的时候调用(每个只调用一次

顺序:

  1. 先调用父类的+load ,再后调子类的+load
  2. 按照编译先后顺序调用(先编译,先调用

     

4.+initialize方法?

  • +initialize方法会在类第一次接收到消息时调用 (如[Person alloc])
  • 调用顺序
    先调用父类的+initialize,再调用子类的+initialize
    (先初始化父类,再初始化子类,每个类只会初始化1次)
  • 如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
  • 如果分类实现了+initialize,就覆盖类本身的+initialize调用 (+initialize是通过objc_msgSend进行调用)

5.关联对象

  • 关联对象并不存储在被关联对象本身内存中
  • 所有的关联对象存储在全局统一的AssociationsManager中
  • value传nil就自动抹除掉关联对象

  Ket常见用法:

  1. A. static const char NAME_CHAR; // static 只在当前文件作用域,别的地方不能extern调
  2. static const void *key = &key; // 取地址 key
  3. @selector(name) (_cmd) // getter
  4. @”name” // 属性名字字符串

   objc_AssociationPolicy(没有weak):

  • OBJC_ASSOCIATION_ASSIGN : assign
  • OBJC_ASSOCIATION_RETAIN_NONATOMIC : strong, nonatomic
  • OBJC_ASSOCIATION_COPY_NONATOMIC : copy, nonatomic
  • OBJC_ASSOCIATION_RETAIN : strong, atomic
  • OBJC_ASSOCIATION_COPY : copy, atomic

  原理:

  • AssociationsManager
    • AssociationsHashMap
      • ObjectAssociationMap
        ○  ObjcAssociation

发表回复

电子邮件地址不会被公开。 必填项已用*标注

Protected with IP Blacklist CloudIP Blacklist Cloud