首先声明OC的内存管理机制:引用计数。

当一个对象的引用计数为0时,这个对象就会被释放。

铭记以上两点,我们开始来探讨。

换句话说,如果一个对象,没有强指针指向,就会被释放。

举个很形象的例子,假如每一个对象都是一只狗,每一个强指针都是狗链子,狗链子的数量就是引用计数。那么情况就会变成这样:当一个狗没有被狗链子拴着的时候,它就跑了。哈哈~

那么什么情况下又会造成循环引用呢?顾名思义,就是两个对象相互强引用,就会导致retain cycle.根据OC的内存管理机制,只有引用计数为0的时候对象才会被释放。很显然循环引用的直接结果就是导致两个对象都释放不掉造成内存泄漏。
举一个非常简单的循环引用的例子:

NSMutableArray *arr1 = [NSMutableArray array];
NSMutableArray *arr2 = [NSMutableArray array];
[arr1 addObjectsFromArray:arr2];
[arr2 addObjectsFromArray:arr1];

很明显,arr1和arr2谁都不会被释放,因为它们相互持有。
也是因此,代理属性要声明为assign或者weak,那同理,block也要注意循环引用。
但是代理和block声明的时候是相反的,代理要用weak,block要用copy.

为什么代理用weak或assign?

我们在ViewController.h中声明一个委托,并写一个代理属性。

然后在ViewController.m中调用代理

在SecondViewController.m中遵守协议,并成为ViewController的代理,实现代理方法。

上图少了一行代码:[self.view addSubview:viewVC.view]这里的重点是,viewVC.delegate = self; 这一行代码,这时,我们回看在ViewController中的代理属性@property(nonatomic, weak) id delegate. 相当于这个id类型现在就是SecondViewController类型,换句话说,就是ViewController对SecondViewController进行了引用,这里是weak,所以是弱引用。而SecondViewController对ViewController进行了强引用。
所以,如果delegate属性声明为strong,就会造成循环引用。

为什么Block属性用copy

内存分为五个区:栈区、堆区、常量区、代码区、静态区(全局区)。

Block用copy修饰可以拷贝到堆区,以便我们程序员管理。它本身默认是在栈区,由系统管理,什么时候释放不确定,为了避免访问野指针,所以应该把它放在堆区。

注意:在ARC下,声明出来的block属性,不管用strong还是copy,编译器都会对这个block进行copy操作。即便如此,还是推荐使用copy来修饰,这样也能提醒你,编译器会对block进行copy操作。

另一方面,block也会经常导致循环引用,所以通常的做法就是,在外部创建一个weakSelf(用__weak修饰的self),来防止循环引用。这里最好在block内部再声明一个strongSelf(用__strong来修饰weakSelf).这是因为保证代码在执行block期间,self不会被释放,当block执行完后,会自动释放该strongSelf;

探讨OC的内存管理 以及防止循环引用retain cycle 代理为什么用weak block为什么用copy相关推荐

  1. 十二:内存简单介绍和OC的内存管理

    一.内存简单介绍 内存结构 1.运行时分配 (1)栈:用户存放程序临时创建的局部变量(先进后出). (2)堆:动态分配内存段. 2.编译器分配 (1)BSS段:存放未初始化的全局变量和静态变量. (2 ...

  2. 关于OC的内存管理-01

    1.什么是内存管理? 大家都知道手机的内存是有限的,app应用的内存也应该是受限制的,随着app应用的使用会导致内存的占用率增大.当内存占用率达到一种程度时.系统会发出内存警告.这时我们须要把一些不用 ...

  3. Objective-C基础笔记(3)OC的内存管理

    Objective-C的内存基本管理 在OC中每一个变量都保存着引用计数器,当这个对象的引用计数器为0的时候该对象会被回收.当使用alloc.new或者copy创建一个对象的时候,对象的引用计数器被置 ...

  4. 【iOS高级资深工程师面试篇】④、2022年,金九银十我为你准备了《iOS高级资深工程师面试知识总结》 内存管理部分2/2 引用计数-弱引用-自动释放池-循环引用

    iOS高级资深工程师面试篇系列 - 已更新3篇 UI部分1/3 -UITableView-事件传递&视图响应 UI部分2/3 -图像显示原理-UI卡顿&掉帧 UI部分3/3 -UIVi ...

  5. iOS之深入解析内存管理NSTimer的强引用问题

    一.强引用问题分析 现在有两个控制器 A.B,从 A push 到 B 控制器,在 B 控制器中有如下代码: self.timer = [NSTimer timerWithTimeInterval:1 ...

  6. OC内存管理常见面试题整理

    1:简述OC中内存管理机制.与retain配对使用的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?readwrite,rea ...

  7. Objective-c:内存管理

    基本原理 简介 内存管理是程序设计中常见的资源管理的一部分.每个计算机系统可供程序使用的资源都是有限的,这些资源包括内存.打开文件.数量及网络连接等等.如果你使用了某种资源,例如因为打开文件而占用了资 ...

  8. iOS之深入解析内存管理的引用计数retainCount的底层原理

    一.简介 ① 引用计数概念 OC 在创建对象时,不会直接返回该对象,而是返回一个指向对象的指针. OC 在内存管理上采用了引用计数,它是一个简单而有效管理对象生命周期的方式. 在对象内部保存一个用来表 ...

  9. 内存二三事: Xcode 内存图、Instruments 可视化检测循环引用

    小结下,内存管理的语义: 需要该对象的时候,他就得在.不需要他的时候,他最好被释放了. 合理的利用资源. 需要该对象的时候,他不在,释放早了. 野指针问题,用僵尸对象调试 给他发消息,程序会崩,EXC ...

  10. IOS第四节:OC中的内存管理机制

    [自动释放池] [autorelease方法和自动释放池] 每一个对象都有一个autorelease方法,调用autorelease方法之后不会像调用release方法一样马上释放对象, 当一个对象调 ...

最新文章

  1. Sping面试题 Top 50
  2. 扩增子统计绘图1箱线图:Alpha多样性
  3. swift_029(Swift 的泛型)
  4. Vue.js 状态管理
  5. Android之网络请求通过协程+okhttp的没有做网络异常处理导致程序奔溃问题
  6. html分块时边距的设置,html – 文本节点后第一个块的边距(垂直空间)?
  7. java 中equals和==的区别
  8. ruby 查看csv文件_如何使用CSV和Ruby构建终端游戏
  9. python 线程间通信之Condition, Queue
  10. css属性之box-shadow
  11. mysql 日期格式
  12. python安装教程-最新Python安装图文教程[很详细]
  13. C#基础温习(10):C#实现托盘功能
  14. 无法启动此程序 因为计算机中丢失msvcr71.dll,msvcr71.dll丢失怎样修复?计算机中丢失msvcr71.dll的解决方法...
  15. 企业邮箱能帮企业带来哪些好处?
  16. 实现浏览器多标签页通信
  17. 什么是光开光?它有什么作用?
  18. 随机数的产生原理与实现
  19. Qt编写的项目作品7-视频监控系统
  20. HTML+CSS大作业: 个人介绍网页制作作业 大学生简单个人静态HTML网页设计作品 DIV布局个人介绍网页模板代码 DW学生个人博客网站制作成品下载

热门文章

  1. 程序员 谨防猝死
  2. c语言函数fac,将一个求阶乘的函数fac专门写在一个文件file1.cpp中,定义为外部函数。然后在另一文件file2.cpp中...
  3. 教你如何在闲鱼买二手iPhone
  4. 阿里云的DMZ区网络
  5. Java问题排查系列--线上问题排查的方法/步骤
  6. NPM 2FA双重认证的设置方法
  7. QT5.12静态编译手册
  8. php的变量命名规则
  9. 中国大学MOOC中国文化概论试题(含答案)
  10. Oracle 中数据类型变更无效 ---ora-22858:数据类型的变更无效 for clod