1. 程式人生 > >xcode 編譯器是如何發現程式碼中出現了”迴圈引用”的

xcode 編譯器是如何發現程式碼中出現了”迴圈引用”的

場景

122764502-678e234dd8378be4

有時候寫程式碼會出現這樣的警告 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 會把它釋放掉的。

按照這個規則,那麼問題來了,看下面幾個例子。

132764502-ddceeb8fc0eadcb9 迴圈引用.png

編譯器如何發現迴圈引用

用了圖論中的拓撲排序,拓撲排序是不能排有環的圖的,所以用它來對一個圖排序,如果排序失敗了就表示出現了環(即發生了迴圈引用),排序成功就表示沒有環。

今天又看了一遍拓撲排序的定義,以前上離散數學的時候聽過,現在有點忘了,百度百科的定義是

由某個集合上的一個偏序得到該集合上的一個全序,這個操作稱之為拓撲排序。

舉個例子說清偏序,全序

142764502-1604a0e91626ca52

拓撲排序過程比較直觀了,步驟如下:
1.遍歷圖中入度為 0 的節點,全部加入到棧中。(上圖的 a)
2.從棧中拿出一個節點,把它指向的節點的入度全部減一。
3.重複1,2步驟直到棧空。

如果圖中的點全都被訪問過,表示沒有環,如果還有無法訪問的節點,表示出現了環,排序失敗。即出現了“迴圈引用”的情況。

最後發個以前寫的拓撲排序的程式碼(下載地址