阅读 94

iOS OC对象详解

OC的实现

OC的对象、类主要是基于C、C++的结构体来实现的。 编写的 OC代码,底层实现其实都是C、C++代码。

OC对象的本质

// NSObject对象在源码的实现
struct NSObject_IMPL {
    Class isa;
};
复制代码

一个NSObject对象占用多少内存?

NSObject对象内部只有一个isa指针,在64bit的环境下,指针占用8个字节,所以NSObject对象实际只使用了8个字节,但是在ios的64bit操作系统中,分配内存规则是16的倍数,所以一个NSObject对象占用16个字节。(通过malloc_size函数可以验证)

利用clang将OC类转换成C++的文件

生成全部架构的C++文件
clang -rewrite-objc main.m -o main.cpp

生成Xcode上指定arm64架构的C++文件
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
复制代码

通过函数计算内存大小

#import <objc/runtime.h>
#import <malloc/malloc.h>

NSObject *obj = [[NSObject alloc] init];

// 计算对象需要多少内存
NSLog(@"%zu",class_getInstanceSize([NSObject class]));

// 计算实际分配多少内存
NSLog(@"%zu",malloc_size((__bridge const void *)(obj)));
复制代码

Xcode实时查看内存数据

image.png

LLDB实时查看内存数据

image.png

OC对象的分类

1.实例对象(instance)

实例对象就是类通过alloc出来的对象,每次调用alloc都会产生新的实例对象。
存储的信息:
isa指针
其他的成员变量
NSObject *object = [[NSObject alloc] init];
复制代码

2.类对象(class)

每个类在内存中有且只有一个类对象,通过class方法获取。
存储的信息:
isa指针
superclass指针
类的属性信息
类的对象方法信息
类的协议信息
类的成员变量信息
Class objectClass = [NSObject class];
复制代码

3.元类对象(meta-class)

元类对象是类的对象,每个类在内存中有且只有一个元类对象,通过object_getClass(类对象)获取,元类和类的结构是一样的,只是地址不同,存储的值不同。
存储的信息:
isa指针
superclass指针
类的类方法信息
#import <objc/runtime.h>
Class objectmetaclass = object_getClass([NSObject class]);
复制代码

补充说明

1.class方法返回的对象只会是类对象,不会是元类对象,即使[[NSObject class] class]也是一样。

2.object_getClass返回的是传入对象的isa指针指向的对象,是最真实的类对象。

3.査看class是否为元类

BOOL result = class_ismetaClass([NSObject class]);
复制代码

4.本文如有侵犯隐私或其他请联系我,我将在第一时间整改或删除。