小谷底层探索合集缓存
兄弟们。十一假期玩的爽吗。小生睡了7天,可谓是美滋滋啊。😆markdown
应用的启动过程
应该有些了解了,因为我偷懒(在睡觉),因此就没有写应用启动的博客了)我就简单的写下哈。。就不带你们一步一步走了(见谅见谅~),你们有时间的话仍是能够调试走一波的。app
有点简陋。函数
应用启动
首先调用的是_dyld_start
,而后调用objc源码
的第一个方法是_objc_init
(这个就是今天要研究的东西~)oop
void _objc_init(void)
{
static bool initialized = false;
if (initialized) return;
initialized = true;
// fixme defer initialization until an objc-using image is found?
environ_init();
tls_init();
static_init();
runtime_init();
exception_init();
cache_init();
_imp_implementationWithBlock_init();
_dyld_objc_notify_register(&map_images, load_images, unmap_image);
#if __OBJC2__
didCallDyldNotifyRegister = true;
#endif
}
复制代码
environ_init(); //环境变量的读取初始化
tls_init(); //自动释放池、runloop线程相关
static_init(); //运行C ++静态构造函数
runtime_init(); //新增的。runtime运行时环境初始化
exception_init(); //异常捕获初始化
cache_init(); //缓存条件初始化
_imp_implementationWithBlock_init(); //启动回调机制
复制代码
好吧,以上都不是要探究的重点~😆,这里先不作解释了。源码分析
_dyld_objc_notify_register
是此次探究的。肉眼可见和dyld有关联~ 咱们点进去以后发现:跟不进去了~post
objc
源码中不能继续探究,并且还和dyld
有关联,那咱们想一想一下会不会调用了dyld
源码。dyld
源码发现:void _dyld_objc_notify_register(_dyld_objc_notify_mapped mapped,
_dyld_objc_notify_init init,
_dyld_objc_notify_unmapped unmapped)
{
dyld::registerObjCNotifiers(mapped, init, unmapped);
}
复制代码
void registerObjCNotifiers(_dyld_objc_notify_mapped mapped, _dyld_objc_notify_init init, _dyld_objc_notify_unmapped unmapped) {
// record functions to call
sNotifyObjCMapped = mapped;
sNotifyObjCInit = init;
sNotifyObjCUnmapped = unmapped;
// call 'mapped' function with all images mapped so far
try {
notifyBatchPartial(dyld_image_state_bound, true, NULL, false, true);
}
catch (const char* msg) {
// ignore request to abort during registration
}
// <rdar://problem/32209809> call 'init' function on all images already init'ed (below libSystem)
for (std::vector<ImageLoader*>::iterator it=sAllImages.begin(); it != sAllImages.end(); it++) {
ImageLoader* image = *it;
if ( (image->getState() == dyld_image_state_initialized) && image->notifyObjC() ) {
dyld3::ScopedTimer timer(DBG_DYLD_TIMING_OBJC_INIT, (uint64_t)image->machHeader(), 0, 0);
(*sNotifyObjCInit)(image->getRealPath(), image->machHeader());
}
}
}
复制代码
objc
源码跨库调用dyld
源码,而后dyld
源码在调用了objc
源码~_dyld_start
,而后调到_objc_init
,以后又跨库调用了dyld
,而后目的仍是调用map_images
和load_images
.兄弟们~ 这幅图我尽力了
毕竟不是灵魂画家😆ui