注:本文集为自己准备面试时,系统复习的笔记,如大家有兴趣,欢迎阅读并指正
1.autoreleaspool有什么用,什么时候创建,什么时候释放?
2.__strong、__weak、assign的修饰符的底层实现,引用计数器的位置?
3.什么是消息转发和消息查找?如何捕捉崩溃?
4.分类为什么没有属性?分类和扩展区别,为什么分类不可以添加属性,扩展可以?
1、内存布局
- 代码区:程序代码
- 全局区:未初始化及已初始化。
- 堆区:低地址到高地址
- 栈区:高地址到低地址
2、内存管理方案
- TaggedPointer:小对象管理
- NONPOINTER_ISA:非指针性的isa指针
arm64架构:64个比特位。- 第一位:是否是纯指针,如果否表示含有引用技术表
- 第二位:是否有关联对象
- 第三位:表示是否含有c++的内容
- 第4位-第37位:当前位的类对象指针地址
- 第42位:弱引用表
- 第43位:是否正在deallocating操作
- 第44位:散列表
- extra_rc:存储<10的引用计数器
- 散列表(引用计数表和弱引用表)
- Slide Tables(): 包含Slide Table的数组,为哈希表,
- Slide Table:包含spinlock_t(自旋锁)、RefcountMap(引用计数表)、weak_table_t(弱引用表)
- 为什么不是一个Slide Table而是Tables?
存在改变对象有读写安全问题,读写安全需要加锁,因此为提高效率分成多个table。
ps:散列表本质就是一张哈希表,实现快速分流,什么是哈希表?
ptr->f(ptr) ->index
3、数据结构
Spinlock_t
- spinlock_t是“忙等”的锁,适用于轻量访问
- 自旋锁和普通的锁有什么区别?适用于哪些场景?
RefcountMap:引用技术表,哈希表。适用哈希为了提高查找效率
weak_table_t:弱引用表。key:对象指针、value:weak修饰的指针
4、MRC和ARC
MRC:手动引用计数。
ARC:是LLVM和Runtime协作的结果。禁止手动调用retain/release/retainCount/dealloc
5、引用计数管理
dealloc释放过程:
dealloc方法实现如下图
image.png
判断是否是pointer_isa,weak表,关联对象,c++,slidtable表是否释放
object_dispose()方法实现如下图
image.png
6、弱引用原理
- 声明
__weak声明的指针,经过编译器声明,会调用objc_initWeak()方法继续调用storeWeak()方法,最后会调用weak_register_no_lock()方法进行弱引用变量添加,具体添加的位置是通过哈希算法查找到index,如果存在,添加到原有的数组中,如果没有创建弱引用数组,index=0存放改指针。 - 清除
weak_clear_no_lock()。当一个对象dealloc,dealloc方法中会对weak清除的函数,会根据当前对象指针查找弱引用表,把当前对象相对应的引用都拿出来数组,并把当前数组所有指针置为nil。
7.自动释放池
- AutoreleasePool的实现原理是怎样的?
- AutoreleasePool为何可以嵌套使用?
@autoreleasepool{}
// => 等价于
void *ctx = objc_autoreleasePoolPush();
{}
objc_autoreleasePoolPop(ctx);
什么是自动释放池?
- 以栈为结点通过双向链表的形式组合而成的数据结构,是和线程一一对应
自动释放池什么时候创建,什么时候销毁?
8、循环引用?
- 自循环引用
- 相互循环引用,__block可以使用循环引用?
- 多循环引用
是否在开发过程中碰到循环引用问题,你是怎么解决的?
Block循环引用
NSTimer循环引用
网友评论