![](/img/trans.png)
[英]Why observer stay alive after a view controller is deinitialized and causes SIGABRT or EXC_BAD_ACCESS?
[英]View Controller is not deinitialized when expected
我試圖了解在串行異步 DispatchQueue中執行任務和在方法/函數中執行相同任務之間的區別,方法是通過來自同一個DispatchQueue的弱 self引用它。
代碼 - 1
asyncAfter 塊在 1.5 秒后執行,而task()正在處理這會關閉視圖 controller 但deinit()僅在task()完成后調用。
class NewViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5, execute: {
self.dismiss(animated: false, completion: nil)
})
let queue = DispatchQueue(label: "myQueue", qos: .default)
queue.async {[weak self] in
self?.task()
}
}
private func task() {
print("start")
for i in 0...10000000 {
if i%500 == 0 {
}
}
print("stop")
}
deinit {
print("deinit")
}
}
控制台 output = 開始停止 deinit
代碼 - 2
在這種情況下,在視圖 controller 被關閉后,按預期調用deinit() 。
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5, execute: {
self.dismiss(animated: false, completion: nil)
})
let queue = DispatchQueue(label: "myQueue", qos: .default)
queue.async {[weak self] in
print("start")
for i in 0...10000000 {
if i%500 == 0 {
}
}
print("stop")
}
}
deinit {
print("deinit")
}
控制台 output = 啟動 deinit 停止
有人可以解釋為什么兩者之間有區別嗎?
盡管兩個閉包都使用了weak self
,但第一個閉包在視圖 controller 上調用了 function。 這會導致視圖 controller 被保留,直到 function 返回。
如果不是,則視圖 controller 將被釋放,而 function 仍在執行,這將是一件壞事
在第二個閉包中,沒有對self
的引用,因此閉包只是由調度隊列保留。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.