ios的oc语法底层是基于c语言来实现的,为了更好的了解ios的一些底层的东西,首先我们将oc转成c语言,具体方法如下。
打开终端,输入xcodebuild -showsdks
可以获取到本地上所装的SDK。
接下来cd到你要rewrite的文件的目录下,如果该文件没有依赖第三方库或者framework的话,直接
xcrun -sdk iphonesimulator11.2 clang -rewrite-objc main.m
如果依赖framework,则
xcrun -sdk iphonesimulator11.2 clang -rewrite-objc -F /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk ViewController.m
此时可以获取到一个.cpp文件。打开后可以看到整个文件的底层C语言实现。
先输入一个block块代码。(block函数的语法和使用比较简单,不讲)
将其转化之后,得到
我们将viewdidload里面的方法调用取出来
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"));
int num1 = 30,num2 =50;
int (*myBlock)(int a) = ((int (*)(int))&__ViewController__viewDidLoad_block_impl_0((void *)__ViewController__viewDidLoad_block_func_0, &__ViewController__viewDidLoad_block_desc_0_DATA, num1, num2));
((int (*)(__block_impl *, int))((__block_impl *)myBlock)->FuncPtr)((__block_impl *)myBlock, 100);
}
首先我们注意到viewDidLoad的方法传入了两个参数,这两个参数被称作隐式参数。self不多介绍,_cmd的作为一个SEL指针类型,指向某一个函数的IMP指针。
这里执行的操作就是:初始化一个block实例,交给我们这么myBlock名字变量,也就是用myBlock这个指针指向这个block实例,执行的时候,直接找到这个block中的指向函数地址的指针。int (*myBlock)(int a)这个则是C语言经