原文地址https://www.jishudog.com/8744/html
iOS程序下内存布局
不同内存布局区域的含义
stack(栈):方法调用
heap(堆):通过alloc等分配的对象
bss:未初始化的全局变量
data:已初始化的全局变量
text:程序代码
2.ARC 自动引用计数
alloc
经过一系列调用,最终调用的C函数malloc,此时并没有设置引用计数为1(但是通过retainCount得知是1,在后面会讲到)
retain
经过两次Hash查找,找到对应的引用计数值,然后进行+1的操作
release
经过两次Hash查找,找到对应的引用计数值,然后进行-1的操作
retainCount
经过两次Hash查找,找到对应的引用计数值,然后与1相加(因此刚alloc的对象,在对应的引用计数表中实际是没有这个映射的)
dealloc
判断时候可以释放的条件(五个条件缺一不可)
[图片上传失败…(image-584a89-1608785619322)]
object_dospose()函数内部实现分析
clearDeallocating()内部实现
weak变量的添加过程
如何添加weak变量的?
对象指针在经过编译器的编译之后调用objcinitweak(),然后storeweak()方法,经过一系列的函数调用,最终在weakregisternolock()进行弱引用变量的添加,通过hash算法位置查找,如果已经存在当前对象对应的弱引用数组,则直接加进去,如果没有则创建新个新的弱引用数组,存放新的weak指针
系统如何实现将废弃的weak指针置为nil
系统如何实现将废弃的weak指针置为nil?
当对象被dealloc后废弃之后,会调用弱引用清除的相关函数。然后在函数实现中,根据当前对象指针,查找弱引用表,把当前对象对应的弱引用都拿出来,然后遍历所有的弱引用指针置为nil
AutoreleasePool是以栈为结点,通过双向链表的形式组合而成的数据结构。编译器会将@autoreleasepool{}改写,如下 图。实际objc_autoreleasePoolPop函数在内部做了pop操作,批量将autoreleasepool中的所有的对象都会做一次release操作
编译器改写@autoreleasepool{}
什么是双向链表?
双向 链表结构[obj autorelease]的实现(对象加入自动释放池)
先判断当前next指针是否指向栈顶,如果不是直接加入;如果是,则增加一个栈结点到链表上,在新的栈添加对象;移动next指针
插入哨兵对象
多次插入哨兵对象,也就是对一个新的releasePool的创建,如果当前栈没有满,则不需要创建新的page,如果满了,新增一个栈节点
答:在档次runloop将要结束的时候调用AutoreleasePoolPage:pop(),对array对象执行release操作
在for循环中,alloc图片数据等内存消耗较大的场景手动插入autoreleasePool,每一次for循环都进行一次内存的释放,降低内存消耗
自循环引用 对自身强持有
相互循环引用
多循环引用
文章到这里就结束了,你也可以私信我及时获取面试资料。如果你有什么意见和建议欢迎给我留言。