1、内存管理方案
1)对于小对象使用TaggedPointer,如NSNumber
2)NONPOINTER_ISA:64位系统下,isa指针占用64位,其中32位或者40位代表了Class地址,其他的位数存储了内存管理方面的相关内容
3) 散列表,包括了引用计数表和弱引用表
散列表结构:本质上是一个哈希表
2、添加weak变量
被声明为__weak的指针,被编译过后会调用objc_initWeak()函数,然后经过storeWeak()函数,最终在weak_register_no_lock()函数中被添加到弱引用表中。具体添加位置是通过哈希算法来进行位置查找,如果对应位置已经有当前对象所对应的弱引用数组,我们就将新的弱引对象添加到数组中。如果没有我们新创建弱引用数组,将对象添加在第0个位置。
3、weak修饰变量释放后,weak指针置为nil流程
当一个对象被delloc后,在delloc内部实现中会调用weak_clear_no_lock的清除弱引用方法,方法中会通过哈希查找查找到当前对象的弱引用数组,然后遍历分别置为nil。
4、AutoReleasePool实现原理
1)是以栈为结点通过双向链表的形式组合而成的数据结构
2)是和线程是一一对应的
5、AutoreleasePoolPage::pop
1)根据传入的哨兵对象找到对应的位置
2)给你上次push操作之后添加的对象一次发送release消息
3)回退next指针到正确位置
6、AutoreleasePool
1)在当次RunLoop将要结束的时候调用AutoreleasePoolPage::pop
2)多层嵌套就是多次插入哨兵对象。
3)在for循环中alloc图片数据等内存消耗较大的场景手动插入autoreleasePool
7、NSTimer引起的循环引用
1)在停止Timer时将timer置为nil
2)使用中间对象,弱引用timer和原对象
8、如何破除循环引用
1)避免产生循环引用
2)在合适的时机手动断环
具体方案:
1)__weak
2)__block
1、在MRC下,__block修饰对象不会增加其引用计数,避免了循环引用
2、在ARC下,__block修饰对象会被强引用,无法避免循环引用,需要手动解环。
3)__unsafe_unretained
1)修饰对象不会增加其引用计数,避免了循环引用
2)如果被修饰对象在某一时机被释放,会产生悬垂指针。
网友评论