[英]Confusion about where should put the [unowned self]
我有一個保留周期,所以我的viewcontroller的deinit將不會被調用,我正在嘗試解決這個問題,我添加[unowned self],但是我不太確定在我的情況下將無主的放在哪里:
class YADetailiViewController: UIViewController {
var subscription: Subscription<YAEvent>?
override func viewDidLoad() {
super.viewDidLoad()
if let query = self.event.subscribeQuery() {
self.subscription = Client.shared.subscribe(query)
self.subscription?.handle(Event.updated) {
query, object in
DispatchQueue.main.async {
[unowned self] in// Put unowned here won't break the cycle, but it does compile and run
self.pageViewLabel.text = String(object.pageViews) + " VIEW" + ((object.pageViews > 1) ? "S" : "")
}
}
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
if let query = self.event.subscribeQuery() {
self.subscription = Client.shared.subscribe(query)
self.subscription?.handle(Event.updated) {
[unowned self] query, object in // Put unowned breaks the cycle, and deinit is called
DispatchQueue.main.async {
self.pageViewLabel.text = String(object.pageViews) + " VIEW" + ((object.pageViews > 1) ? "S" : "")
}
}
}
}
我很好奇這兩種情況之間的區別是什么,為什么一種有效而另一種無效
實際上,正如@matt正確提到的那樣,問題與捕獲self
的時間有關。 事實上,此代碼self
被捕獲兩次:
handle
方法時 async
方法時(在handle
閉包執行期間) 外部封閉件需要self
將其傳遞到內部封閉件,否則內部封閉件將無法捕獲它。
性質或保留周期如下: self
(YADetailiViewController) - > subscription
- > closure( handle
parameter) - > self
。 要打破這個循環,就不能在那個(外部)閉包中保留self
。 這就是第二個代碼示例有效的原因。
第二次捕獲self
(在內部閉包中)僅在外部閉包執行時發生並持續到執行async
塊 - 通常是很短的時間。
在第一個代碼示例中,您沒有打破循環。 self
的第二次捕獲不會發生,但第一次捕獲(造成你的周期)仍然存在。
如果在視圖控制器已被刪除/釋放時仍然可以調用handle
閉包,那么按照@AdrianBobrowski的建議,您應該使用weak
而不是unowned
以防止可能的崩潰。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.