美文网首页
2、alloc分析、源码调试(2)

2、alloc分析、源码调试(2)

作者: 白马啸红中 | 来源:发表于2020-09-16 15:02 被阅读0次

3、objc4源码调试(\color{red}{基于iOS 13.7,xcode 11.7, MacOS 10.15.6,objc4-781})

main方法中代码如下:

#import <Foundation/Foundation.h>
#import "LGPerson.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
       //我这里源码是加了init,也可以不加,不影响结果,why?-可以删掉走流程一下
        NSObject *objc1 = [[NSObject alloc] init];
        LGPerson *objc2 = [[LGPerson alloc] init];

        NSLog(@"Hello, World! %@ - %@",objc1,objc2);
    }
    return 0;
}

首先针对objc1进行分析,先通过打开汇编开关打开,\color{red}{Debug-Debug\ Workflow -Always\ Show\ Disassembly},勾选上。

NSObject汇编分析 这里居然不是进入\color{red}{\_objc\_rootAlloc}方法,和上一篇对不上号了,换一个试试对象objc2还是一样,源码不对了?怀疑人生了~

继续分析,记住这个\color{indigo}{objc\_alloc\_init},关闭汇编开关,搜索这个方法,找到并加入断点,重新运行一下程序,发现果然objc1和objc2都调用这个\color{indigo}{objc\_alloc\_init}方法,而且继续调用了\color{indigo}{callAlloc}方法。

objc_alloc_init方法 继续进入这个方法打上断点进行单步跟踪 callAlloc方法 这里发现了NSObject这个类的流程直接走了\color{indigo}{\_objc\_rootAllocWithZone}方法,但是LGPerson类是先走的最后一句调用\color{indigo}{alloc}方法,赶紧搜索\color{indigo}{alloc}方法断点,果然进去了而且还发现了一个神奇的方法~ Alloc方法 没错就是\color{indigo}{\_objc\_rootAlloc}方法继续跟进的话就是再进入一次\color{indigo}{callAlloc}方法然后调用\color{indigo}{\_objc\_rootAllocWithZone},哇~这里我上篇符号断点调试LGPerson类方法调用流程统一了,源码不曾欺我也~。
但是这里也出现了两个问题:
\color{red}{1、NSObject没有走alloc方法,而是直接走的objc\_alloc\_init方法}
\color{red}{2、LGPerson会走callAlloc两次}

遇到问题不能放过这就要分析。
\color{red}{第一个问题}
源码是没办法发现了,所以只有查看系统级LLVM源码,Android Studio中打开源码,搜索objc_alloc_init,搜到

shouldUseRuntimeFuctionForCombinedAllocInit方法 这个应该是方法调用的版本判断的,继续搜索这个方法 tryEmitSpecializedAllocInit方法 这个方法的最后是调用的EmitObjCAllocInit方法,继续搜索这个方法: 调用objc_alloc_init方法 这里发现最终还是调用了objc_alloc_init方法。同理,如果你搜索objc_alloc也会最终追踪到这个文件里面调用了objc_alloc方法,第一个问题,OVER。
\color{red}{第二个问题}
LGPerson初始化进行单步跟踪,进入到 callAlloc方法发现会先走objc_msgSend发送alloc消息继续跟进会第二次走callAlloc方法就会进入_objc_rootAllocWithZone方法,第二个问题,OVER。

相关文章

网友评论

      本文标题:2、alloc分析、源码调试(2)

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