返回

OC对象底层内存开辟和实现(下)

IOS

在上一节中,我们研究了ObjC和LLVM源码底层关于alloc的实现过程,并了解了如何识别记录类的各种状态。我们还总结并解释了提出的相关问题。在这节中,我们将继续研究alloc后续关于内存开辟、内存对齐和类绑定的内容。

内存开辟

在ObjC中,对象在堆上分配。当调用alloc时,系统会为对象分配一段连续的内存空间。这块内存空间的大小由类的实例大小决定。类的实例大小是类中所有成员变量的大小之和。

在LLVM中,内存开辟是由malloc函数完成的。malloc函数会从堆上分配一段连续的内存空间,并返回这块内存空间的起始地址。

内存对齐

在ObjC中,对象必须按照一定的对齐方式进行分配。对齐方式是指对象在内存中存放的位置必须是某个特定值的整数倍。例如,在32位系统中,对象必须按照4字节对齐,而在64位系统中,对象必须按照8字节对齐。

内存对齐是为了提高程序的性能。当对象按照对齐方式分配时,可以减少对齐操作的次数,从而提高程序的运行速度。

类绑定

在ObjC中,每个对象都必须绑定到一个类。类绑定是指将对象与类的元数据相关联。元数据包括类的名称、类的实例大小、类的成员变量等信息。

类绑定是在objc_allocateClassPair函数中完成的。objc_allocateClassPair函数会创建一个新的类,并将这个类与一个元数据结构相关联。

类绑定之后,就可以使用objc_msgSend函数来调用对象的方法。objc_msgSend函数会根据对象的类信息,找到相应的方法并执行。

代码示例

// 创建一个新的类
Class MyClass = objc_allocateClassPair(NSObject.class, "MyClass", 0);

// 添加成员变量
objc_property_t property = objc_property_t{
  "name",
  "NSString *",
  objc_property_attribute_t{0, "C"},
  0,
  0,
  0,
  0
};
objc_addProperty(MyClass, property);

// 注册类
objc_registerClassPair(MyClass);

// 创建一个对象
id object = [[MyClass alloc] init];

// 调用方法
[object performSelector:@selector(setName:) withObject:@"John"];

// 获取属性值
NSString *name = [object performSelector:@selector(name)];

NSLog(@"%@", name);

这段代码创建一个新的类MyClass,并添加一个名为name的成员变量。然后将该类注册到系统中,并创建一个对象。最后,调用方法并获取属性值。

总结

在这篇文章中,我们研究了OC对象底层内存开辟和实现的后续内容,包括内存开辟、内存对齐和类绑定等方面。我们还提供了相关代码示例,有助于深入理解OC对象的底层实现原理。