【IOS】[[NSObject alloc]init]

经常用

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 准确来说是返回一个实例对象的成员变量所需要空间大小
\color{red}{ 间大小 }

但是实际分配了多少?从malloc_size 结果来看,是分配16个字节空间,但是class_getInstanceSize算到只需要8就够了,为什么系统却给了16?

NSObject *obj = [[NSObject alloc]init];
这就一句代码,alloc就是跟内存分配相关的。

可以看苹果开源的代码:https://opensource.apple.com/tarballs/
看下alloc的实现过程:

image.png

这是一个objc库,对应源码上的是这个(下载最新版本):
image.png

这里梳理了一下调用过程:

  1. image.png
  2. image.png
  3. image.png
  4. image.png
image.png
回头看下instanceSize的实现:
image.png

这里可以看到

// CF requires all objects be at least 16 bytes. 意思是要求所有的对象至少要16字节。因此对于[NSObject alloc] 经过instanceSize 出来后,必定是16,oalloc开辟给它的也是16了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容