美文网首页
iOS底层 -- 内存管理之copy、weak原理

iOS底层 -- 内存管理之copy、weak原理

作者: happy神悦 | 来源:发表于2020-10-12 10:44 被阅读0次
一、copy
  • 拷贝的目的:产生一个副本对象,跟源对象互不影响
  • 修改了源对象,不会影响副本对象
  • 修改了副本对象,不会影响源对象
iOS提供了2个拷贝方法
  • copy 不可变拷贝,产生不可变副本
  • mutableCopy可变拷贝,产生可变副本

深拷贝和浅拷贝

  • 深拷贝 内容拷贝,产生新的对象
  • 浅拷贝 指针拷贝,没有产生新的对象

copy和mutableCopy 图解

1.copy都是不可变拷贝,产生不可变副本mutableCopy都是可变拷贝,产生可变副本
2.除了不可变对象copy浅拷贝,其他都是深拷贝

二、引用计数的存储

在64bit中,引用计数可以直接存储在优化过的isa指针中,也可能存储在SideTable类中

  • refcnts是一个存放着对象引用计数的散列表
三、weak实现原理 - dealloc

当一个对象要释放时,会自动调用dealloc,接下的调用轨迹是

1.dealloc 调用流程

  • 1.首先调用 _objc_rootDealloc()

  • 2.接下来调用 rootDealloc()

  • 3.这时候会判断是否可以被释放,判断的依据主要有 5 个,判断是否有以上五种情况

    • NONPointer_ISA
    • weakly_reference
    • has_assoc
    • has_cxx_dtor
    • has_sidetable_rc
  • 4-1.如果有以上五中任意一种,将会调用 object_dispose()方法,做下一步的处理。

    • 4-2.如果没有之前五种情况的任意一种,则可以执行释放操作,C 函数的 free()。

    • 5.执行完毕。

2.object_dispose() 调用流程。

  • 1.直接调用 objc_destructInstance()。

  • 2.之后调用 C 函数的 free()。

3.objc_destructInstance() 调用流程

  • 1.先判断 hasCxxDtor,如果有 C++ 的相关内容,要调用 object_cxxDestruct() ,销毁 C++ 相关的内容。

  • 2.再判断 hasAssocitatedObjects,如果有的话,要调用 object_remove_associations(), 销毁关联对象的一系列操作。

  • 3.然后调用 clearDeallocating()。

  • 4.执行完毕。

4.clearDeallocating() 调用流程。

  • 1.先执行 sideTable_clearDellocating()。
  • 2.再执行 weak_clear_no_lock,在这一步骤中,会将指向该对象的弱引用指针置为 nil。
  • 3.接下来执行 table.refcnts.eraser(),从引用计数表中擦除该对象的引用计数。
  • 4.至此为止,Dealloc 的执行流程结束。
四、weak修饰的对象释放则自动被置为nil的实现原理:

Runtime维护了一个weak表,存储指向某个对象的所有weak指针。weak表其实是一个hash(哈希)表,Key是所指对象的地址,Value是weak指针的地址数组(这个地址的值是所指对象的地址)。

weak 的实现原理可以概括一下三步:

1、初始化时:runtime会调用objc_initWeak函数,初始化一个新的weak指针指向对象的地址。

2、添加引用时:objc_initWeak函数会调用 objc_storeWeak()函数, objc_storeWeak() 的作用是更新指针指向,创建对应的弱引用表。

3、释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。

相关文章

网友评论

      本文标题:iOS底层 -- 内存管理之copy、weak原理

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