如何运用clang来探索OC对象的本质
2022-09-07 本文已影响0人
今年27
Clang
clang是一个由Apple主导编写,基于LLVM的C/C++/OC的编译器
主要是用于底层编译,将一些文件``输出成c++文件,例如main.m 输出成main.cpp,其目的是为了更好的观察底层的一些结构 及 实现的逻辑,方便理解底层原理。
在普通工程中
在main中自定义一个类LGPerson,有一个属性name
@interface LGPerson : NSObject
@property (nonatomic, copy) NSString *name;
@end
@implementation LGPerson
@end
通过终端,利用clang将main.m编译成 main.cpp,有以下几种编译命令,这里使用的是第一种
//1、将 main.m 编译成 main.cpp
clang -rewrite-objc main.m -o main.cpp
//2、将 ViewController.m 编译成 ViewController.cpp
clang -x objective-c -rewrite-objc -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk SomeFile.m
//以下两种方式是通过指定架构模式的命令行,使用xcode工具 xcrun
//3、模拟器文件编译
xcrun -sdk iphonesimulator clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
//4、真机文件编译
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
打开编译好的main.cpp,找到LGPerson的定义,发现LGPerson在底层会被编译成 struct 结构体
LGPerson_IMPL中的第一个属性 其实就是 isa,是继承自NSObject,属于伪继承,伪继承的方式是直接将NSObject结构体定义为LGPerson中的第一个属性,意味着LGPerson 拥有 NSObject中的所有成员变量。
LGPerson中的第一个属性 NSObject_IVARS 等效于 NSObject中的 isa
//NSObject的定义
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
//NSObject 的底层编译
struct NSObject_IMPL {
Class isa;
};
//LGPerson的底层编译
struct LGPerson_IMPL {
struct NSObject_IMPL NSObject_IVARS; // 等效于 Class isa;
NSString *_name;
};
main.cpp
通过这样之后方便我们来探索底层