iOS知识总结备份-原创

2020-03-14  本文已影响0人  秋S寂S

从业iOS以来,基本的一些知识点总结,尽量用自己的话通俗易懂的方式去解释,原创,不定时更新。有不完善或者错误的地方,欢迎指正,感谢

一些基础概念

两者区别:
①类别中原则上只能增加方法(能添加属性的的原因只是通过runtime解决无setter/getter的问题而已);
②类扩展不仅可以增加方法,还可以增加实例变量(或者属性),只是该实例变量默认是@private类型的(
用范围只能在自身类,而不是子类或其他地方);
③类扩展中声明的方法没被实现,编译器会报警,但是类别中的方法没被实现编译器是不会有任何警告的。这是因为类扩展是在编译阶段被添加到类中,而类别是在运行时添加到类中。
④类扩展不能像类别那样拥有独立的实现部分(@implementation部分),也就是说,类扩展所声明的方法必须依托对应类的实现部分来实现。
⑤定义在 .m 文件中的类扩展方法为私有的,定义在 .h 文件(头文件)中的类扩展方法为公有的。类扩展是在 .m 文件中声明私有方法的非常好的方式。

内存管理

内存管理详解

内存布局:
----------------

内核区:用于操作系统的使用

----------------   0xc0000000

栈区:函数、方法、临时变量、指针 等等
        V
        V
        V
---------------- 

两边往中间靠,如果相遇了,造成了堆栈溢出

----------------
        ^
        ^
        ^
        ^
堆区:存放alloc, new变量

----------------

未初始化的数据 .bss (静态区)

----------------

已初始化的数据 .data (常量区)

----------------

代码区:代码段 .text

----------------   0x00400000

保留区

----------------


栈区 0x7 存放常量,静态变量。  
堆区 0x6 存放对象

对象取值过程: 通过指针(栈区),获取到堆区的内存空间,读到值

原则一: 多用函数,嵌套方法,用空间换时间

TaggedPointer : 简单的小对象 存储, 它的地址不再地址,而是真正的值,不存于堆区。


isa: 被优化过的联合体(union),每一位的值代表不同的含义

离散表 sideTable:包含自旋锁,引用计数

对象的 retainCount = 1 + extra_rc + sideTable。在调用retain 的时候,首先会在isa 的 extra_rc 里面 +1,如果超出了最大值,这会将其中的一半 RC_HALF 保存到散列表里。在调用release 方法时,先在 extra_rc 里 -1,如果为0了,查找散列表中是否有值,有的话 取出 RC_HALF-1 存到extra_rc中,如果此时 retainCount 为 0 了,则发送 dealloc消息

自动释放池原理

1. 首先是什么:自动释放池是一个结构体,包含了 AutoreleasePoolPush,AutoreleasePoolPop。是以 AutoreleasePoolPage 作为结点的双向链表来实现的。
2. 其次作用是什么:自动释放池的作用,在它的作用空间中,大括号内,将对象添加到自动释放池中,随后结束的时候,给对象发送release消息,延迟释放对象。
3. 怎么添加的:page 对象包含了 parent,child,等信息,在 压栈push 对象之前,会先插入一条边界符,并将当前的 page 对象setHot 激活状态,等容器存满之后,再插入边界符,开启下一个 page 容器,child 指向 最新的那个page,新的 page 就会设置setHot
4. 怎么pop:找到最底下的 page,将其中的对象一个一个发送release 消息,然后遇到 边界符 时,会先找到 parent,然后将其 child 置为 nil,并setHot。一直递归,直到所有的都释放了。
5. runloop与自动释放池的关系:runloop 在响应事件时,会调用 autoreleasePoolPush,将后续的一系列对象添加到自动释放池中,最后它休眠又会去调用 pop。从而达到销毁对象的目的。

KVC && KVO

对象通信( KVO & 通知 & 代理 & Block)

runtime

runloop

1 通知 observers 即将进入 run loop
2 通知 observes 即将开始处理 timer source
3 通知 observes 即将开始处理 source0 事件
4 执行 source0 事件
5 如果处于主线程有 dispatchPort 消息,跳转到第9步
6 通知 observes 线程即将进入休眠
7 内循环阻塞等待接收系统消息,包括:
8 收到内核发送过来的消息 (source1消息)
9 定时器事件需要执行
10 run loop 的超时时间到了
11 手动唤醒 run loop
12 通知 observes 线程被唤醒
13 处理通过端口收到的消息:
14 如果自定义的 timer 被 fire,那么执行该 timer 事件并重新开始循环,完成后跳转到第2步
15 如果 input source 被 fire,则处理该事件
16 如果 run loop 被手动唤醒,并且没有超时,完成后跳转到第2步
17 通知 observes run loop 已经退出
上一篇 下一篇

猜你喜欢

热点阅读