OC底层基础

一、+load方法

  • +load方法会在runtime加载类、分类时调用

  • 每个类、分类的+load,在程序运行过程中只调用一次

  • 调用顺序

    1. 先调用类的+load
      • 按照编译先后顺序调用(先编译,先调用)
      • 调用子类的+load方法之前会先调用父类的+load
    2. 再调用分类的+load
    • 按照编译先后顺序调用(先编译,先调用)
  • objc4源码解读过程:objc-os.mm

    1. _objc_init

    2. load_images

    3. prepare_load_methods

      • schedule_class_load
      • add_class_to_loadable_list
      • add_category_to_loadable_list
    4. call_load_methods

      • call_class_loads
      • call_category_loads
      • (*load_method)(cls,SEL_load)
  • +load方法是根据方法地址直接调用,并不是经过objc_msgSend函数调用

二、+initialize方法

  • +initialize方法会在类第一次接收到消息时调用

  • 调用顺序

    1. 先调用父类的+initialize,再调用子类的+initialize
    2. (先初始化父类,再初始化子类,每个类只会初始化一次)
  • +initialize+load的最大区别是,+initialize是通过objc_Send进行调用的,所以有以下特点

    1. 如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
    2. 如果分类实现了+initialize,就覆盖类本身的+initialize调用
  • objc4源码解读过程

    1. objc-msg-arm64.s
      • objc_msgSend
    2. objc-runtime-new.mm
      • class_getInstanceMethod
      • lookUpImpOrNil
      • lookUpImpOrForward
      • _class_initialize
      • callInitialize
      • objc_msgSend(cls,SEL_initialize)

三、__weak问题解决

  • 在使用clang转换OC为C++代码时,可能会遇到以下问题
    1. cannot create __weak reference in file using manual reference
  • 解决方案:支持ARC、指定运行时系统版本,比如
    1. xcrun -sdk iphoneos clang -arch ram64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-12.0.0 main.m

你可能感兴趣的:(OC底层基础)