2016-09-16 75 views
2

在調用dismissViewControll之後,我一直使用協議和委託方法將數據傳遞迴前一個VC。下面就是我通常會做,因爲它是不是這樣,大多數教程編寫弱代理和類協議

protocol someVCDelegate { 
    func somefunction() 
} 

var delegate: someVCDelegate! 

不過,我碰到寫它的這個類/弱的辦法。

protocol someVCDelegate : class { 
    func somefunction() 
} 

weak var delegate: someVCDelegate! 

我明白,弱與ARC相關聯,並避免保留週期。但是,我不知道什麼時候我需要它,因爲在我所有的情況下,沒有做弱代理作品發現(VC確實不行)。在什麼情況下我需要弱代表?另外,它爲什麼是「!」弱後,通常是「?」後弱了吧?

+0

你是否在任何時候讓代表零?或者前一個VC不保留對下一個VC的引用?我懷疑爲什麼在VC上調用deinit,如果一個對象至少有一個強引用它,ARC不會清理它。因此,如果前面的VC引用了下一個VC,並且下一個VC具有對之前的(強)委託引用,那麼ARC將不會刪除它們,如果它們失去所有其他引用導致內存泄漏 – Fonix

+0

它始終是一種很好的做法,無論如何,它並不困難,並且可以爲您節省一些未來的麻煩。可能難以調試,如果它稍後成爲問題 – Fonix

+0

今天剛剛閱讀。它爲我澄清了一些疏忽:ARC。 https://www.raywenderlich.com/134411/arc-memory-management-swift – Adrian

回答

2

你說:

但是,我不知道,當我需要它在我所有的情況下,不這樣做弱的代表作品

你只需要微弱的協議,委託模式當你有一個強大的參考週期的潛力,即一系列強大的參考循環。例如,考慮:

  • 具有屬性(「子」)的對象(「父」),即父對子具有強引用;

  • 孩子有delegate財產;和

  • 您設置孩子的delegate來引用父對象。

在這種情況下,它的關鍵,該委託是weak引用,否則你就會有很強的參考週期。

請注意,這是一個微不足道的例子,有時強引用鏈可能相當複雜。例如,考慮具有委託屬性的UIView子類。從視圖控制器到其根目錄view,通過子視圖的一系列子視圖,一直到UIViewdelegate,潛在的強參考週期可能是相當長的,可能會引用回視圖控制器。這也將導致強烈的參考週期,因此我們傾向於使用delegateweak參考。

但是,當您使用協議委託模式在視圖控制器之間傳遞數據時,這通常不是問題(視圖控制器遏制除外),因爲呈現視圖控制器不擁有呈現的視圖控制器。視圖控制器層次通常保持對視圖控制器的強引用。所以,當你關閉所提供的視圖控制器時,它將被解除分配,並且可能的強參考週期得到解決。

通常,我們會本能地採用weak協議委託模式(僅僅因爲它阻止了強參考週期的發生)。但有時你會使用強大的參考。最常見的強參考模式是NSURLSession,其delegate是一個有力的參考。由於documentation for init(configuration:delegate:delegateQueue:)警告我們:

會話對象保持較強的參考delegate,直到你的應用程序退出或明確的會話無效。如果您不通過調用invalidateAndCancel()finishTasksAndInvalidate()方法使會話失效,則應用程序會泄漏內存直到退出。

雖然這看起來似是而非,這種強烈的參考模式的優點是會話知道它可以安全地調用其委託的方法,而不必擔心其被釋放的對象。 (順便說一下,NSURLSession這個強大的代表行爲很少會出現醜陋的頭部,因爲我們經常使用完成處理程序方法,根本不使用委託方法,而且當我們使用委託方法時,我們經常會有其他對象而不是視圖控制器作爲會話的代表)。

總之,您真的必須評估每種情況,並確定我們本能地傾向於的弱引用是否更好,或者您是否有其中一種情況協議最好配合強大的參考。

0

爲什麼它很弱:弱引用是一個引用,它不會強制保留它引用的實例,因此不會停止ARC處置引用的實例。此行爲可防止參考成爲強參考週期的一部分。或者簡單地說,通過將類之間的某些關係定義爲弱引用或無主引用而不是強引用來解決強引用週期。

它是「!」因爲它被隱式地解開,所以很弱。它會有一個價值。

有時從程序的結構中可以清楚地看到,在第一次設置值之後,可選項將始終有一個值。在這些情況下,每次訪問時都不必檢查和打開可選的值,因爲可以安全地假定所有時間都有值。