閉包產生循環引用的前提:
(1)將閉包賦值給一個類的屬性。
(2)這個背包中訪問了實例的某個屬性或者方法。
這中情況導致閉包捕獲了self,而self強引用了閉包。這就導致了循環引用。
解決方案:
定義捕獲列表:在定義閉包時,同時定義捕獲列表作為參數的一部分。通過這種方式可以解決閉包和類實例之間的循環強引用。捕獲列表定義了閉包體內捕獲一個或者多個引用類型的規則。跟解決兩個實例間的循環強引用一樣,聲明每個捕獲的引用為弱引用或者無主引用,而不是強引用。應根據代碼關系來決定使用弱引用還是無主引用。
如果閉包沒有指明參數列表或者參數類型,即他們會通過上下文進行推斷。那么可以把捕獲列表和關鍵字in放在閉包最開始的地方。
如果閉包有參數和返回值類型,把捕獲放在他們前面。
到底是采用unowned還是采用self?當閉包和捕獲的實例總是同時銷毀,將閉包內的捕獲定義為無主引用。相反的,在捕獲的引用可能變為nil時,將閉包內的捕獲定義為弱引用。弱引用總是可選類型,而且當引用的實例被銷毀后,弱引用的值會自動置為nil。這使我們可以在閉包體內檢查他們是否存在。