xcode编译器是如何发现代码中出现了”循环引用”的

场景

有时候写代码会出现这样的警告 Capturing 'self' strongly in this block is likely to lead to a retain cycle。意思是说在 block 里面写了强引用的 self 可能会导致"循环引用"。

什么是循环引用

这个我不打算细说了,网上大把关于循环引用的文章,自己上谷歌去百度一下就知道了。大概说一下就是 iOS 的 ARC 内存管理方式导致的。一个对象(Controller,View,Model等等都是对象)如果被 strong 指针指着,ARC 是不会去释放它的,如果被 weak 指针指着,ARC 会把它释放掉的。

按照这个规则,那么问题来了,看下面几个例子。

xcode编译器是如何发现代码中出现了”循环引用”的_第1张图片
循环引用.png

编译器如何发现循环引用

用了图论中的拓扑排序,拓扑排序是不能排有环的图的,所以用它来对一个图排序,如果排序失败了就表示出现了环(即发生了循环引用),排序成功就表示没有环。

今天又看了一遍拓扑排序的定义,以前上离散数学的时候听过,现在有点忘了,百度百科的定义是

由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。

举个例子说清偏序,全序

xcode编译器是如何发现代码中出现了”循环引用”的_第2张图片

拓扑排序过程比较直观了,步骤如下:
1.遍历图中入度为 0 的节点,全部加入到栈中。(上图的 a)
2.从栈中拿出一个节点,把它指向的节点的入度全部减一。
3.重复1,2步骤直到栈空。

如果图中的点全都被访问过,表示没有环,如果还有无法访问的节点,表示出现了环,排序失败。即出现了“循环引用”的情况。

最后发个以前写的拓扑排序的代码(下载地址)

你可能感兴趣的:(xcode编译器是如何发现代码中出现了”循环引用”的)