系统底层源码分析(15)——对象的本质
2021-06-18 本文已影响0人
无悔zero
我们写一段代码,然后编译成cpp文件:
@interface Person : NSObject
{
NSString *nikename;
}
@property (nonatomic, copy) NSString *name;
@end
@implementation Person
@end
将
.m
文件由 OC 转 C++ 源码方法如下:
打开终端,执行cd 文件所在目录
命令,
然后执行clang -rewrite-objc xxx.m
,
之后xxx.m
所在目录下就会生成一个xxx.cpp
文件,这就是相关的 C++ 源码。
//编译后
extern "C" unsigned long OBJC_IVAR_$_Person$_name;
struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS;
NSString *nikename;
NSString *_name;//生成下划线
};
//getter
static NSString * _I_Person_name(Person * self, SEL _cmd) { return (*(NSString **)((char *)self + OBJC_IVAR_$_Person$_name)); }
extern "C" __declspec(dllimport) void objc_setProperty (id, SEL, long, id, bool, bool);
//setter
static void _I_Person_setName_(Person * self, SEL _cmd, NSString *name) { objc_setProperty (self, _cmd, __OFFSETOFIVAR__(struct Person, _name), (id)name, 0, 1); }
对象的本质就是结构体。
用@@property
写的属性和大括号里写的成员变量区别就是,属性名生成下划线,生成getter
和setter
方法。
实际上我们编写的 OC 代码,最终都是转成了
runtime
库的东西。比如:
- 类转成了
Runtime
库里面的结构体等数据类型;- 方法转成了
Runtime
库里面的 C 语言函数;- 调用方法转成了
objc_msgSend
函数(所以说 OC 有个消息发送机制)