OC对象的底层实现
将.m文件转换为.cpp文件
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o 输出的CPP文件
参数解释
-sdk 指定平台
-arch 指定架构
-o 指定输出文件
main.m 为编写的OC源文件
main.cpp 为编译后的C++目标文件
消息机制
在main.cpp中的最后找到我们的main方法和创建NSObject对象的语句
int main(int argc, char * argv[]) {
{ __AtAutoreleasePool __autoreleasepool;
NSObject * obj = objc_msgSend(objc_msgSend(objc_getClass("NSObject"), sel_registerName("alloc")), sel_registerName("init"));
}
return 0;
}
NSObject * obj = [[NSObject alloc] init];
分为两步执行
第一步
NSObject * obj = [NSObject alloc];
NSObject * obj = objc_msgSend(objc_msgSend(objc_getClass("NSObject"), sel_registerName("alloc"))
通过函数objc_msgSend向NSObject这个类发送alloc消息, 返回一个对象
第二步
obj = [obj init];
obj = objc_msgSend(obj, sel_registerName("init"));
通过函数objc_msgSend向[NSObject alloc]创建的对象发送init消息, 返回一个初始化好的对象
OC中类的底层实现
// OC代码
@interface NSObject {
Class isa;
}
// 底层实现
struct NSObject_IMPL {
Class isa;
};
// Class
typedef struct objc_class *Class;
// objc_class
struct objc_class : objc_object {
// ...
}
// objc_object
struct objc_object {
Class ISA();
// ...
}
OC中的类是通过C++的结构体来实现的
自定义类CLPerson
// 源代码
@interface CLPerson : NSObject
{
NSInteger no;
NSInteger age;
}
@end
// 底层实现
struct CLPerson_IMPL {
struct NSObject_IMPL NSObject_IVARS;
NSInteger no;
NSInteger age;
};
/**
NSObject_IMPL这个结构体只有一个Class isa;
所以CLPerson的底层实现相当于下面这样
*/
struct CLPerson_IMPL {
Class isa;
NSInteger no;
NSInteger age;
};
通过结构体指针改变对象成员变量的值
让结构体指针指向对象, 通过结体指针修改所所指对象成员变量的no, age的值
CLPerson * p = [[CLPerson alloc] init];
p -> no = 1001;
p -> age = 16;
printf("p - no: %ld, p - age: %ld \n", p -> no, p -> age);
struct CLPerson_IMPL * p2 = (__bridge struct CLPerson_IMPL *)p;
p2 -> no = 2002;
p2 -> age = 18;
printf("p - no: %ld, p - age: %ld \n", p -> no, p -> age);
OC对象的分类
NSObject * obj1 = [[NSObject alloc] init];
NSObject * obj2 = [[NSObject alloc] init];
printf("实例对象: %p, %p \n", obj1, obj2);
Class cls1 = [obj1 class];
Class cls2 = [obj2 class];
Class cls3 = object_getClass(obj1);
Class cls4 = object_getClass(obj2);
printf("类对象: %p, %p, %p, %p \n", cls1, cls2, cls3, cls4);
Class mCls = object_getClass([NSObject class]);
printf("元类对象: %p \n", mCls);
实例对象: 0x283038120, 0x283038110
类对象: 0x1ed193218, 0x1ed193218, 0x1ed193218, 0x1ed193218
元类对象: 0x1ed1931f0
instance对象 / 实例对象
obj1, obj2是两个不同的实例对象, 有着不同的内存
内存中的信息主要包括
主要包括
- isa指针
- 其它成员变量
class对象 / 类对象
cls1, cls2, cls3, cls4是同一个类对象, 有着同一块内存, 有且只有一个
内存中的信息主要包括
- isa指针
- superclass指针
- 成员变量信息
- 属性信息
- 对象方法信息
- 协议信息
meta-class对象 / 元类对象
mCls是一个元类对象, 在内存中有且只有一个
内存中的信息主要包括
- isa指针
- superclass指针
- 类方法信息