2017-04-25 57 views
1

在迅速的,我可以用實例方法爲關閉,例如,分配方法回調快捷方式關閉保留實例嗎?

self.someView.someCallback = self.doSomething 

那麼,是self強烈此處引用的self.doSomething?上面的行是否創建了一個參考循環?

+0

查看此問題以供參考:http://stackoverflow.com/questions/24320347/shall-we-always-use-unowned-self-inside-closure-in-swift –

+0

@DejanSkledar:沒有答案問題適用於我的。 –

+0

@Rob:你是在回答我的問題還是隻是重複它? –

回答

1

如果doSomethingself的實例方法,則是,該行建立強引用。

如果doSomething不是一個函數,而是一個閉包,那麼該線本身並不建立一個強引用,而是它成爲一個問題,閉包本身是否指self,如果它確實,是否存在[weak self][unowned self]捕獲列表。

0

爲了有一個保留週期,則需要對每個方向一個有力的參考,即:

對象的強引用對象B

對象B強烈的引用對象A

假設self中您分享的代碼是視圖控制器,並假設是一個強烈的參考視圖,我們可以說即:

對象A(視圖控制器)強烈引用對象B(部分視圖)

現在,如果對象B(部分視圖)具有很強的參考回視圖控制器,你將有一個保留週期。

假設doSomething是你的ViewController的方法,而不是關閉,你將有一個保留週期

一個簡單的方法來檢查這一點,是由於兩種你實施deinit有些查看和你視圖控制器,就像這樣:

class SecondViewController: UIViewController { 

    var someView: CustomView? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     someView = CustomView(frame: view.frame) 
     someView?.someCallback = doSomething 
    } 

    func doSomething() { 
    } 

    deinit { 
     print(#function) 
    } 
} 

final class CustomView: UIView { 
    var someCallback: (() -> Void)? 

    deinit { 
     print(#function) 
    } 
} 

您將看到print S於deinit永遠不會打印出來在控制檯。但是改變分配someCallback的方式:

someView?.someCallback = { [weak self] in 
    self?.doSomething() 
} 

會導致deinit運行,從而打破了保持週期

編輯:

甚至,作爲一種替代方案:

weak var weakSelf = self 
someView?.someCallback = weakSelf?.doSomething 

儘管這是使用弱引用,因爲此表達在被執行的someCallback分配的時間來評價,而不是在它被執行的時間,這將仍然成爲strong參考) - 感謝@Rob

+1

好點@Rob,已經更新了我的答案。 – Edgar