load 和 initialize

2020-04-11  本文已影响0人  张_何

load

load 函数调用解析

在运行时加载程序时会调用call_load_methods()函数

void call_load_methods(void) {
  ....
  do{
        while(loadable_classes_used > 0) {
              call_class_loads(); //调用类的+load 方法
        }
        more_categories = call_category_loads(); //调用分类的 +load 方法
  } while (loadable_classes_used > 0 || more_categories);
  ...
}

根据以上代码我们可以知道,先调用类的 load方法,类的 load方法调用完才会调用分类的load方法。那么这里为什么跟我们OC 的消息机制不一样呢?oc 的消息机制不是去方法列表里面去找,找到后直接调用吗?如果按照 OC 的消息机制先找到的应该是分类中的方法,应该调用分类的方法才正确呀!其实这里主要是因为load方法并不是走 OC 的消息机制,而是通过类找到load方法直接调用的。分类的load 方法也是直接找通过分类找到load方法然后直接调用的

// 类的 load 方法调用
for (i = 0; i < used; i++) { 
  Class cls =classes[i].cls;
  load_method_ t load_method = (load_method_t)classes[i].method; //取出类的 load 方法直接调用。这里 method 就是指向 load 方法。
....
}
// 分类的 load 方法调用
for (i = 0; i < used; i++){
  Category cat = cats[i].cat;
  load_method_ t load_method = (load_method_t)cats[i].method;//取出分类的 load 方法直接调用
....
}
//先调用父类的 load 方法,后调用子类的 load 方法.这里是一个递归调用,保证父类先调用,然后调用子类。
static void schedule_class_load(Class cls) {
  if(!cls) return;
  assert(cls->isRealized());
  if(cls->data()->flags & RW_LOADED) return;
  schedule_calss_load(cls->superclass);// 保证先调用父类的
  add_class_to_loadable_list(cls); //将 cls 天剑到 loadable_classes数组的最后面
  cls->setInfo(RW_LOADED);
}

initialize

initialize 方法调用解析

load 和 initialize 的区别

上一篇下一篇

猜你喜欢

热点阅读