简单记录一下在 Xcode 中是如何查看函数调用的,先来一段简单的代码。
CZPerson *p = [[CZPerson alloc] init];
[p isKindOfClass:[NSObject class]];
[p eat];
然后在需要的地方打一个断点,这里我们要看下 isKindOfClass底层,调用的什么函数,在 [objc isKindOfClass:[NSObject class]];的下一行打断点,除此之外还需要需要设置 Xcode 的 Debug的选项
Xcode -> Debug -> Debug Workflow -> Always show Disassembly
然后运行一下工程,运行到断点处,就会看到下面的函数调用
稍微解释一下,第一个函数 objc_alloc_init对应 [[CZPerson alloc] init];,接着会调用 objc_opt_class,对应的是 [NSObject class],然后就是我们的主角 objc_opt_isKindOfClass ,对应isKindOfClass。从这里可以得出 isKindOfClass 底层调用的是 objc_opt_isKindOfClass 函数。
另外来看一下 [p eat]; 的调用过程
这里的函数调用过程走的是 Objective-C 中的消息发送 objc_msgSend
和之前的几个进行对比就会发现,关于 Objective-C 的对象创建, 获取 class 和调用 isKindOfClass 都是直接使用 runtime 中的函数。至于为什么是直接调用相关函数,这是编译器对这些方法的优化,在LLVM的源码中有体现(看别人说的0 0,应该也没精力去看了)