我们平时编写的Objective-C代码,底层实现其实都是C\C++代码,Objective-C的面向对象都是基于C\C++的结构体来实现的。所以我们所写的Objective-C代码最终都会转成C\C++代码,再由C\C++代码转成汇编语言代码,最后再转成机器语言。
相同的一份代码在转成C\C++代码时,对于不同平台所生成的代码是不一样的,再转成汇编语言时不同平台也是不一样的,而且汇编语言是完全依赖于硬件的,不同的硬件环境所生成的的汇编语言完全不一样。
我们可以通过终端命令来将Objective-C代码转成C\C++代码。首先在终端将当前目录移动到OC文件所在目录,main.m的OC代码转成main.cpp的c++代码:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp
xcrun表示利用xcode工具。-sdk iphoneos用于指定SDK,表示说生成的c++代码是运行在iPhone上的。clang是苹果的clang编译器。-arch arm64是指定架构,对于iOS平台,模拟器的架构是i386,32位机器的架构是armv7,64位机器的架构是arm64。-rewrite-objc aaa.m表示重写aaa.m文件的代码。-o bbb.cpp表示重写的代码输出为c++代码并保存再bbb.cpp文件中。
如果运行上面命令报错xcrun: error: SDK "iphoneos" cannot be located,那我们需要先运行下面这条命令来给Xcode命令行工具指定路径:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/
比如main.m文件的代码如下:
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person = [[Person alloc] init];
}
return 0;
}
转换成c++文件后代码有几万行,把代码拉到最下面就可以看到main函数转换后对应的c++代码,代码如下:
int main(int argc, const char * argv[]) {
/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
Person *person = ((Person *(*)(id, SEL))(void *)objc_msgSend)((id)((Person *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));
}
return 0;
}