Objetive-C +load方法研究
- load方法的执行时机
Objetive-C 的runtime会在一个类的所有方法加载到内存中时调用这个类的+load() 方法,因为每个类的方法只是加载一次,所以每个+load()方法只调用一次。
加载一个类的方法会在一个进程启动开始的时候,这个时候进程的业务代码没有还没有开始执行。
对于动态库中的类,类的+load方法会在动态库加载进进程的内存空间时的时候执行
- load的执行次序
+load的方法会从父类到子类的顺序执行,对于一个类的扩展中的Load方法,执行顺序是不确定的。
+load的方法不遵从其它继承方法执行的规律,只有一个类或者扩展存在load方法的时候才会执行。原因是load的方法的imp查找是直接通过特殊的方法查找的,见
/*********************************************************************** * _class_getLoadMethod * fixme * Called only from add_class_to_loadable_list. * Locking: runtimeLock must be read- or write-locked by the caller. **********************************************************************/ IMP _class_getLoadMethod(Class cls_gen) { rwlock_assert_locked(&runtimeLock); class_t *cls = newcls(cls_gen); const method_list_t *mlist; uint32_t i; assert(isRealized(cls)); assert(isRealized(cls->isa)); assert(!isMetaClass(cls)); assert(isMetaClass(cls->isa)); mlist = cls->isa->data()->ro->baseMethods; if (mlist) for (i = 0; i < mlist->count; i++) { method_t *m = method_list_nth(mlist, i); if (0 == strcmp((const char *)m->name, "load")) { return m->imp; } } return NULL; } |
下面是一个Demo
@interface initTest : NSObject
@end
@interface sub1 : initTest
@end
@interface sub2 : sub1
@end
@interface sub2 (category1)
@end
@interface sub2 (category2)
@end
//实现
@implementation initTest
//+(void)initialize //{ // NSLog(@"%s|%@ ",__func__ ,[self class]); //} +(void)load { NSLog(@"%s ",__func__ ); } @end @implementation sub1 //+(void)initialize //{ // NSLog(@"%s|%@ ",__func__ ,[self class]); //} //+(void)load //{ // NSLog(@"%s ",__func__ ); //} @end @implementation sub2 //+(void)initialize //{ // NSLog(@"%s|%@ ",__func__ ,[self class]); //} +(void)load { NSLog(@"%s ",__func__ ); } @end @implementation sub2 (category1) +(void)load { NSLog(@"%s ",__func__ ); } @end @implementation sub2 (category2) +(void)load { NSLog(@"%s ",__func__ ); } @end
|
执行结果如下:
2015-05-26 13:09:37.955 OCinitTest[79585:72506319] +[initTest load]
2015-05-26 13:09:37.956 OCinitTest[79585:72506319] +[sub2 load] 2015-05-26 13:09:37.956 OCinitTest[79585:72506319] +[sub2(category1) load]
2015-05-26 13:09:37.956 OCinitTest[79585:72506319] +[sub2(category2) load]
|
- load方法可以用来做什么
对于一个方法的Swizzle,因为这个时候改变runtime中得方法比执行中改变更安全
分类:
IOS开发问题积累
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架