(一)OC对象本质---内存布局

news/2025/2/22 20:12:31/

Apple OSS Distributions · GitHub
Apple Open Source    开源源码链接

面试题1

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

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

        

  

1)OC中的对象、类主要是基于C\C++的结构体来实现的.C\C++的结构体支撑了我们的面向对象。
Class: 是一个指针  占8个字节。
NSObject *obj = [NSObject alloc ] init];
[NSObject alloc ] init] 就是 分配存储空间给结构体
分配完以后,还有一个指针*,利用这个指针要指向这个对象,就要把对象的内存地址赋值给这个指针。指针存储内存地址,才能找到那个对象。所以这个isa指针的地址,就是结构体在内存中的地址。
isa指针占用了8个字节,但是在alignedInstanceSize里面,小于16会强制使用16个字节。所以分配了16个字节。
如果没有强制16字节,也会有内存对齐规定。内存对齐:为了 提高CPU的访问速度,会进行内存对齐操作。结构体的最终大小必须是最大成员大小的倍数

结构体内存对齐:计算结构体大小的时候 ,内存对齐
操作系统内存对齐:苹果操作系统给分配内存的时候,也存在内存对齐的概念

2)  2个容易混淆的函数

  class_getInstanceSize:成员变量占用的大小(对齐过的)

    size_t class_getInstanceSize(Class cls){if (!cls) return 0;return cls->alignedInstanceSize();}// Class's ivar size rounded up to a pointer-size boundary.uint32_t alignedInstanceSize() {return word_align(unalignedInstanceSize());}// May be unaligned depending on class's ivars.uint32_t unalignedInstanceSize() {assert(isRealized());return data()->ro->instanceSize;}size_t instanceSize(size_t extraBytes) {size_t size = alignedInstanceSize() + extraBytes;// CF requires all objects be at least 16 bytes.if (size < 16) size = 16;return size;}

ps:
  NSLog(@"%zd", class_getInstanceSize([Student class]));   ---->24
​​​​​​​  NSLog(@"%zd", malloc_size((__bridge const void *)stu));  ----->32​​​​​​​

class_getInstanceSize

操作系统,堆空间里面,都是16的倍数。

传递24个字节给calloc,内存对齐后 分配的内存快大小是--->NANO_MAX_SIZE
​​​​​​​#define NANO_MAX_SIZE 256 /* Buckets sized {16, 32, 48, 64, 80, 96, 112, ...} */

id
class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone)
{return _class_createInstanceFromZone(cls, extraBytes, zone);
}static __attribute__((always_inline)) 
id
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, bool cxxConstruct = true, size_t *outAllocatedSize = nil)
{if (!cls) return nil;assert(cls->isRealized());// Read class's info bits all at once for performancebool hasCxxCtor = cls->hasCxxCtor();bool hasCxxDtor = cls->hasCxxDtor();bool fast = cls->canAllocNonpointer();size_t size = cls->instanceSize(extraBytes);if (outAllocatedSize) *outAllocatedSize = size;id obj;if (!zone  &&  fast) {obj = (id)calloc(1, size);if (!obj) return nil;obj->initInstanceIsa(cls, hasCxxDtor);} else {if (zone) {obj = (id)malloc_zone_calloc ((malloc_zone_t *)zone, 1, size);} else {obj = (id)calloc(1, size);}if (!obj) return nil;// Use raw pointer isa on the assumption that they might be // doing something weird with the zone or RR.obj->initIsa(cls);}if (cxxConstruct && hasCxxCtor) {obj = _objc_constructOrFree(obj, cls);}return obj;
}

​​​​​​​


http://www.ppmy.cn/news/467806.html

相关文章

centos使用pip安装ansible

centos使用pip安装ansible 安装ansible需要先安装python&#xff0c;本文是在centos环境先先进行源码安装python3环境&#xff0c;然后利用python3的pip工具进行安装ansible。如果在centos的环境安装python3&#xff0c;可以看这个&#xff1a;centos7源码安装python3 1、使用…

小巧精致的加湿器,走到哪儿都能用

最近发现了一款很别致的加湿器,做得十分小巧,可以在多种环境下使用,而且设计还很有科幻感,这两天试了试,发现确实很好用,北方的冬天空气特别干燥,有了这么个小工具,确实能带来很大帮助。 这是一款来自ORICO的加湿器,感觉质量很不错,设计上也很有新意,平时车载、卧室…

【语音芯片WT2003H赋能加湿器睡眠仪,集语音播报+超声波雾化驱动+触摸功能于一体】

秋冬季节&#xff0c;天气变得干燥异常&#xff0c;我们的身体会处于一个干燥缺水的 状态&#xff0c;多喝水可以缓解缺水状态&#xff0c;而如何提高空气湿度&#xff0c;在干燥的季节 显得尤为重要。今天小编所要讲述的&#xff0c;是如何设计一个简单的加湿器&#xff0c;…

天干物燥,给你写BUG的心来点甘露

程序员的职业注定是需要长期面对电脑 而秋冬长时间面对电脑会有各种小问题 大到秃头&#xff0c;小到皮肤干燥起皮 秃头&#xff0c;它要靠 不加班 霸王洗发露的拯救 而皮肤干燥起皮&#xff0c;只能坚持用护肤水啦 如果不会护肤&#xff0c;那么我们可以让空气变得潮湿起来 今…

一气之下,我实在忍不了了

最近流感太猖獗了&#xff01; 事情还得从前两周说起&#xff0c;天气变化无常&#xff0c;公司里感冒的人多了起来吧。 我其实是一个抵抗力挺差的人&#xff0c;但竟也一直没被传染&#xff0c;就也没放在心上。 就在大家基本都得了一遍流感都快结束的时候&#xff0c;我不幸也…

使用gorm可以通过联结表查询的方式,同时拉取订单记录和每条订单的总价

使用gorm可以通过联结表查询的方式&#xff0c;同时拉取订单记录和每条订单的总价。下面是一个示例代码&#xff1a; package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm""log" )type Goods struct {ID intOrder stri…

使用了并发工具类库,线程安全就高枕无忧了吗?

1、说明 在代码审核讨论的时候&#xff0c;我们有时会听到有关线程安全和并发工具的一些片面的观点和结论&#xff0c;比如“把 HashMap 改为 ConcurrentHashMap&#xff0c;就可以解决并发问题了呀”&#xff0c;“要不我们试试无锁的 CopyOnWriteArrayList 吧&#xff0c;性能…

C++ 封装一个window下载器

文章目录 前言一、原理三、代码四、使用方法前言 想要用C++下载个网上的东西一般都比较麻烦,大多数人都会选择去使用第三方库。 但实际上,windows平台其实已经提供了我们相关的api函数,可以直接在VS中使用,而无需去装其它人写的第三方库,只不过使用起来比较麻烦而已。 …