美文网首页
三、NSObject的alloc源码分析

三、NSObject的alloc源码分析

作者: 顺7zi燃 | 来源:发表于2020-09-11 16:44 被阅读0次

    本章主要分析: 为什么NSObject *objc = [NSObject alloc] 为什么没有走上一章分析的alloc源码的流程

    第一步:探索[NSObject alloc] 走的哪个方法

    • 将断点断在 NSObject *obj = [NSObject alloc];
     NSObject *obj = [NSObject alloc];
     LGPerson *p = [LGPerson alloc];
    
    • 打开 Debug -> Debug workflow -> 勾选 Always Show Disassemly 汇编调试


      NSObject alloc.png

    发现 [NSObject alloc] 并没有走 alloc 方法,而是走 objc_alloc

    第二步:搜索NSObject 为什么走 objc_alloc?
    通过第一步中汇编调试发现:NSObject 和 LGPerson 都调用了 objc_alloc,那么就会有两个问题:

    • 为什么 NSObject 调用 alloc 方法 会走到 objc_alloc?
    • 为什么LGPerson 中的 alloc 会走两次,先调用 objc_alloc,再调用 alloc?
      通过加断点发现 LGPerson 第一次的 alloc 会走 objc_alloc->callAlloc 方法中最后一行代码:objc_msgSend,向系统发送消息
    125.png

    继续执行代码,会走 alloc -> _objc_rootAlloc -> callAlloc上一章分析的alloc源码的流程

    126.png

    所以:LGPerson 走了两次的原因是先执行 objc_alloc ,再通过查找sel,执行 alloc 方法。

    那么问题 为什么会先走 objc_alloc?

    通过 LLVM 源码(llvm-project) 来分析

    • 在源码中搜索 OMF_alloc


      OMF_alloc.png
    • 跳转到 EmitObjCAlloc 方法

    /// Allocate the given objc object.
    ///   call i8* \@objc_alloc(i8* %value)
    llvm::Value *CodeGenFunction::EmitObjCAlloc(llvm::Value *value,
                                                llvm::Type *resultType) {
      return emitObjCValueOperation(*this, value, resultType,
                                    CGM.getObjCEntrypoints().objc_alloc,
                                    "objc_alloc");
    }
    

    所以可以得出:NSObject 中的 alloc 会走 objc_alloc, 其实是由系统级别的消息处理逻辑,所以 NSObject 的 初始化是由系统完成,没有走 alloc 的源码流程。

    总结:NSObject 的 alloc 和 自定义的 alloc 的流程

    NSObject:

    [NSObject alloc] -> objc_alloc -> callAlloc -> _objc_rootAllocWithZone

    自定义类

    [LGPerson alloc] -> objc_alloc -> callAlloc -> objc_msgSend -> alloc -> _objc_rootAlloc -> callAlloc -> _objc_rootAllocWithZone -> _class_createInstanceFromZone

    相关文章

      网友评论

          本文标题:三、NSObject的alloc源码分析

          本文链接:https://www.haomeiwen.com/subject/whjeektx.html