iOS 中内存泄露 - Block就会循环依赖?

Hi,

本文主讲,Block中使用self,为何会循环依赖。


最近公司对代码质量很在意,这是好事。

我们使用Coverityz做了检测,的确有一大堆的问题。

So tm what!

我呢,研究各种case下的问题,以及解决方案。

Now,轮到了内存泄露的case,先来搞这个Block导致的内存泄露,内存常驻吧。反正tm的都是内存浪费。

先来了解下,啥是内存吧,为何泄露?

我简单搜了一下,查看了该猿友的文章http://www.cnblogs.com/houjun/p/4909413.html

通俗点,有的区域(栈)的土地是有人管理的,会进行回收等自动处理,好比说该区域属于国家,你挂了,土地就回收了;有的区域(堆),是公共的,谁都可以用,也没人管理,你只享用某一块空间,却不管清理该空间的废物垃圾,等你挂了,就会影响该空间的再次使用。

当然这也是计算机系统的机制问题,在某些case下某空间无人占领,就该清除,当然也不保证你私藏的电影会不会被清除。


回到主题,为啥内存浪费,该有点头绪了吧,就是没人处理呗。

经常会有人讲,block中使用self会产生循环引用。

他告诉你了规则,那为何产生循环应用?循环引用又咋了?

在下才疏学浅,也是通过查看其他猿友的文章。

http://www.cnblogs.com/biosli/archive/2013/05/29/iOS_Objective-C_Block.html

http://www.cnblogs.com/flyFreeZn/p/4264220.html

我们会想,对象都分配到栈中,就有人管理了,不会有内存泄露的问题了,寡人只想告诉你,有想法是好的,还得按规矩来,哪种case下的对象,在哪里分配空间,是系统决定的。

通过其他猿友的,总结就是ARC下,就是以下两条准则来理解为啥循环依赖、为啥内存常驻了,

声明一个block对象,它是在栈中的;如果Block作为属性property,默认是strong修饰的,我们也会用copy来修饰,两种修饰,都会将Block对象 copy到堆(无人管地带)上。


那么常见问题来了,结合iOS的内存管理机制(引用计数),思路也就有了。

1、临时定义的block,不是copy、strong出来的,如果使用self,不会循环依赖。

为啥咧?因为block中的任务结束(走完{...}),他也就会被处理干净了,相关变量,也会清除,最主要,它在栈中,不信你试试。

当然某些case下,会延迟释放self,比如某个UIViewController的对象中,你在dissmiss页面前,使用performAfter 、dispatch_after来提交了一个任务块(block),里面使用了self,就会延迟释放self,看个人意愿吧,我一般在这种case下,都使用weak,来减少不必要的任务处理。

2、属性block对象中,使用self,会循环依赖,导致self不自动释放,导致内存浪费

为啥咧?因为block此时在堆中,对象self和对象block相互持有对方,导致彼此至少引用计数都是1,tm的谁也没法释放,此时最想说,真是不怕神一样的对手,就怕猪一样的队友。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,285评论 30 472
  • 《Objective-C高级编程》这本书就讲了三个东西:自动引用计数、block、GCD,偏向于从原理上对这些内容...
    WeiHing阅读 9,976评论 10 69
  • 内存管理 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与a...
    丶逐渐阅读 2,034评论 1 16
  • 11.看下面的程序,第一个NSLog会输出什么?这时str的retainCount是多少?第二个和第三个呢? 为什...
    AlanGe阅读 776评论 1 4
  • 禅与 Objective-C 编程艺术 (Zen and the Art of the Objective-C C...
    GrayLand阅读 1,683评论 1 10