美文网首页
iOS知识总结备份-原创

iOS知识总结备份-原创

作者: 秋S寂S | 来源:发表于2020-03-14 11:23 被阅读0次

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

    一些基础概念

    • category(类别):
      应用场景:某些地方,只需要给个别类使用的某些方法,避免子类使用。
      特点:没有属性列表,可以扩展方法,但是可以通过关联对象添加属性

    • extension(扩展):
      场景:平时的.m文件都是,添加方法和实例变量

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

    • 内存分区:代码区、数据区、堆区、栈区

    内存管理

    • 1.iOS的内存管理分MRC 、ARC、自动释放池。
    • 2.iOS的每个一对象都有一个与之对应的引用计数器,叫retaincount,当调用alloc,new, copy方法时,retaincount会加1,当对象调用release方法时,retaincount会减1,当他减到0时,对象就释放了,调用dealloc方法
    • 3.自动释放池并不会销毁对象,而是给作用域的对象发送了release消息。
    • 3.我觉得这主要是解决了数据共享的问题。

    内存管理详解

    内存布局:
    ----------------
    
    内核区:用于操作系统的使用
    
    ----------------   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

    • KVC 键值编码,通过字符串的形式来间接的访问对象属性,给对象属性赋值,而非通过setter,getter方法。这样就可以动态的访问和修改对象属性了。
    • KVC原理:待更新

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

    runtime

    runloop

      1. runloop的作用
      • 保持程序的持续运行
      • 处理App的各种事件(触摸,定时器,performSelector)
      • 节省CPU资源,提高程序的性能
    • 2.runloop与线程的关系:runloop是在线程中创建的,子线程runloop默认是不开启的
    • 3 timer依赖于runloop
    • 4 runtime深入分析。
      runtime包含了mode,observe、source、timer,执行流程如下:
    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 已经退出
    

    相关文章

      网友评论

          本文标题:iOS知识总结备份-原创

          本文链接:https://www.haomeiwen.com/subject/vrgmshtx.html