经常用
NSObject *obj = [[NSObject alloc]init];
很少探究这个过程做的一些事情。
整句代码就是创建了一个oc的实例对象。
整体
image.png这里可以对应的三个值,代表的意义也不同。
sizeof : 是一个运算符来的,不涉及函数运算,其实就计算这个类型占的空间,是类型
class_getInstanceSize : 计算这个实例对象的类需要占用的大小空间,是需要
malloc_size : 这个是系统实际上分配的大小空间,是实际
意思是class_getInstanceSize <= malloc_size。 上面的表述可能不太准确.
也可以这样理解:malloc_size 可以理解为地铁或者公交实际能容下的人数(假如有100个座位),class_getInstanceSize就是当前在地铁或者公交的人数(假如50个人在车上)
先看sizeof:
int 占 4个字节,double 占8 个字节,NSString 占8个字节,float 占4个字节,char 占 1个字节 (都是64位下),这是本来知道的,可以用这些验证sizeof是计算类型占用的大小。
image.png
这样就一目了然
再看class_getInstanceSize 跟 malloc_size:
image.png- class_getInstanceSize : 看苹果源码是返回一个实例对象所占用的内存空间大小。
- malloc_size : 得到内存分配空间大小(Memory alloc)。
那为什么class_getInstanceSize 是 8?
因为就是NSObject 创建出来的对象,所以只能看NSObject。所有的OC代码底层都是C或者 C++实现的。
可以转成C\C++看NSObject
命令:xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc oc文件 -o 要输出的cpp文件名
image.png
image.png
一个oc的viewController类文件,转成c后,几乎全是结构体。(这里可以对一些提游戏马甲包的有一些启发)
image.png
这里看到NSObject的实现,里面其实就只有isa一个指针变量,而指针占8 个字节,也就说NSObject需要占用的就是8个字节。
所以 class_getInstanceSize 准确来说是返回一个实例对象的成员变量所需要空间大小
但是实际分配了多少?从malloc_size 结果来看,是分配16个字节空间,但是class_getInstanceSize算到只需要8就够了,为什么系统却给了16?
NSObject *obj = [[NSObject alloc]init];
这就一句代码,alloc就是跟内存分配相关的。
可以看苹果开源的代码:https://opensource.apple.com/tarballs/
看下alloc的实现过程:
这是一个objc库,对应源码上的是这个(下载最新版本):
image.png
这里梳理了一下调用过程:
- image.png
- image.png
- image.png
- image.png
回头看下instanceSize的实现:
image.png这里可以看到
// CF requires all objects be at least 16 bytes. 意思是要求所有的对象至少要16字节。因此对于[NSObject alloc] 经过instanceSize 出来后,必定是16,oalloc开辟给它的也是16了。
网友评论