iOS-将 .m文件编译成 .cpp文件
Posted MinggeQingchun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS-将 .m文件编译成 .cpp文件相关的知识,希望对你有一定的参考价值。
我们知道OC开发中,创建的对象文件是xxx.h 和 xxx.m,但是有时候我们也需要将 .m文件转为 C++代码的 .cpp文件,如OC中的Runtime
Runtime 是 OC底层的一套C语言的API(需要import导入 <objc/runtime.h> 或<objc/message.h>)
<objc/runtime.h> //包含对类、成员变量、属性、方法的操作;
<objc/message.h> //包含消息机制
编译器最终都会将OC代码转化为运行时代码,通过终端命令编译 .m 文件:
clang -rewrite-objc xxx.m
可以看到编译后的xxx.cpp(C++文件)
比如我们在ViewController.m中创建了一个对象 [[NSObject alloc]init]
- (void)viewDidLoad {
[super viewDidLoad];
NSObject *objc = [[NSObject alloc]init];
}
然后
打开终端Terminal
,cd到文件路径,,然后输入命令
clang -rewrite-objc ViewController.m
这时候终端报错了:
In file included from ViewController.m:8:
./ViewController.h:8:9: fatal error: 'UIKit/UIKit.h' file not found
#import <UIKit/UIKit.h>
^~~~~~~~~~~~~~~
1 error generated.
找不到 'UIKit/UIKit.h' file文件,因此我们需要执行新的命令
clang -x objective-c -rewrite-objc -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk xxx.m
这时候你会发现相应文件夹下多出了一个ViewController.cpp 文件,如下:
我们打开 ViewController.cpp 查看转化后的代码如下:
struct ViewController_IMPL {
struct UIViewController_IMPL UIViewController_IVARS;
};
/* @end */
// @interface ViewController ()
/* @end */
// @implementation ViewController
static void _I_ViewController_viewDidLoad(ViewController * self, SEL _cmd) {
((void (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("ViewController"))}, sel_registerName("viewDidLoad"));
NSObject *objc = ((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("alloc")), sel_registerName("init"));
}
// @end
我们可以看到调用方法本质就是objc_msgSend发消息,[[NSObject alloc]init]
语句发了两次消息,第一次发了alloc 消息,第二次发送init 消息。
我们也可以验证一下
1、调用objc_msgSend
,需要导入头文件#import <objc/message.h>
2、TARGET → Build Settings → 搜索 msg → Enable Strict Checking of objc_msgSend Calls
由YES
改为NO
将严厉的检查机制关掉,如果Enable Strict Checking of objc_msgSend Calls还是YES,则
objc_msgSend的参数会报错
Too many arguments to function call, expected 0, have 2
测试代码:
//obc_msgSend 方法
- (void)testObcMsgSend {
Person *person = [Person new];
[person eat];
objc_msgSend(person,sel_registerName("eat"));
}
输出相同; [person eat];等同于objc_msgSend(person,sel_registerName("eat"));
以上是关于iOS-将 .m文件编译成 .cpp文件的主要内容,如果未能解决你的问题,请参考以下文章