OC的面向对象是怎么实现的?
今天我们来聊一聊OC对象的本质, 我们平时编写的Objective-C代码, 底层实现其实都是C\C++代码.
在我们OC的类中, 可以自由的定义各种各样的属性、成员变量、 实例变量. 那么在底层, 我们的C\C++代码是如何实现的呢, 在我们知道的C\C++数据结构中, 有哪种数据结构可以满足我们的要求呢?
答案是结构体, OC的面向对象都是基于C\C++的结构体实现的。我们可以把OC代码转成C\C++代码来查看它的底层实现, 下面我们就来看看它的底层实现源码.
查看OC对象的底层实现源码
首先, 我们先在Xcode中新建一个macOS的Command Line Tool项目, 里面什么不做
int main(int argc, const char * argv[]) {
@autoreleasepool {
}
return 0;
}
然后, 在Mac电脑终端中,使用$xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 输出C++文件 (如果需要链接其他框架, 使用-framework参数.比如-framework UIKit)
在终端输入命令以后,我们会生成一个main.cpp文件,打开main.cpp文件文件,我们把main.cpp文件拉到最下面,我们会看到这样一段代码
int main(int argc, const char * argv[]) {
/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
}
return 0;
}
这一段底层代码就是我们OC代码中的mian函数的实现。 这时我们在mian函数写入NSObject *obj = [[NSObject alloc] init]; 这一段代码,然后我们点击进入, 查看代码实现
NSObject *obj = [[NSObject alloc] init];
点击NSObject进入内部,可以看到NSObject底层实现
struct NSObject {
Class isa;
};
我们可以看到, 在我们创建的obj对象的底层实现中, 是一个结构体, 这个结构体只有一个isa
对象的isa指针指向哪里?
instance对象的isa指向class对象
class对象的isa指向meta-class对象
meta-class对象的isa指向基类的meta-class对象
OC对象的分类
instance对象(实例对象), 就是通过类alloc出来的对象, 每次调用alloc方法都会产生新的instance对象
NSObject *object1 = [ [NSObject alloc] init];
NSObject *object2 = [ [NSObject alloc] init];
object1、object2是NSObject的instance对象(实例对象), 它们是两个不同的对象, 分别占据着两块不同的内存, instance对象在内存中存储的信息包括: isa指针, 其他成员变量
class对象(类对象)
NSObject *object1 = [ [NSObject alloc] init];
NSObject *object2 = [ [NSObject alloc] init];
Class objClass1 = [object1 class];
Class objClass2 = [object2 class];
Class objClass3 = [NSObject class];
Class objClass4 = object_getClass(object1);
Class objClass5 = object_getClass(object2);
objClass1 ~ objClass5都是NSObject的class对象(类对象), 并且它们都是同一个对象, 每个类在内存中有且只有一个class对象, 它们也不例外
class对象在内存中存储的信息主要包括: isa指针, superclass指针, 类的属性信息(@property)、类的对象方法信息(instance method)、类的协议信息(protocol)、类的成员变量信息(ivar)...
meta-class对象(元类对象)
//通过Runtime API获取NSObject的元类对象
Class objectMetaClass = object_getClass[NSobject class];
每个类在内存中有且只有一个meta-class对象, meta-class对象和class对象的内存结构是一样的, 但是用途不一样, 在内存中存储的信息主要包括: isa指针、 superclass指针、类的类方法信息(class method)...
OC的类信息存放在哪里?
对象方法、属性、成员变量、协议信息, 存放在class对象中
类方法存放在meta-class对象中
成员变量的具体值, 存放在instance对象
未完待续...
网友评论