iOS-探索对象本质

如果想探究OC对象的本质,所以我们需要了解OC这门语言;然后我们也要熟悉研究东西怎么切入

OC的本质

我们平时编写的OC代码,底层实现其实都是C\C++代码

1
OC -> C\C++ -> 汇编语言 -> 机器语言

OC的面向对象都是基于C\C++的数据结构实现的

将Objective-C代码转换为C\C++代码

1
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 输出的CPP文件

如果涉及ARC,需要增加参数

1
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 OC源文件 -o 输出的CPP文件

一个NSObject对象占用对少个字节

  • 系统分配了16个字节给NSObject对象(通过malloc_size函数获得)
  • 但NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInstanceSize函数获得)

参考 objc开放源码

如何查看对象占用空间

1
2
3
4
5
6
#import <objc/runtime.h>
#import <malloc/malloc.h>

NSObject *object = [[NSObject alloc] init];
NSLog(@"%ld", class_getInstanceSize([NSObject class])); // 输出8 - 对象真实占用的地址(内存对齐后)
NSLog(@"%ld", malloc_size((__bridge const void *)object));// 输出16 - 系统真正为该对象分配的空间

OC对象最小分配的空间是 16

内存对齐

为了提高内存的访问效率,争取在一个总线周期就把数据读取到。

在iOS中,CoreFoundation限制了对象最小占用的空间大小。

1
2
3
4
5
6
7
8
9
10
inline size_t instanceSize(size_t extraBytes) const {
if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
return cache.fastInstanceSize(extraBytes);
}

size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
if (size < 16) size = 16;
return size;
}

限制了对齐要求8字节

1
2
3
4
#define WORD_MASK 7UL
static inline uint32_t word_align(uint32_t x) {
return (x + WORD_MASK) & ~WORD_MASK;
}

但是在malloc方法中,又限制了16字节对齐

1
2
#define MALLOC_ALIGNMENT (2 * SIZE_SZ < __alignof__ (long double) \
? __alignof__ (long double) : 2 * SIZE_SZ)