我想退出" DispatchQueue.main.asyncAfter"当deinit被召唤时。
subView.swift
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
self.doSomething()
}
func doSomething(){
if self.subView.flgA == false { //error because subView's deinit is already called
//...
}
}
当ViewController执行_ = self.navigationController?.popViewController(animated: true)
并调用deinit时,在ViewController中调用deinit并首先调用subView,并在几分钟后调用doSomething()
。
我想在执行popViewController时停止doSomething()
。
我该怎么办?
答案 0 :(得分:4)
在Swift中我们有一个名为ARC(Automatic Reference Counting)的东西。 ARC将确保任何具有至少一个强引用的对象不会从内存中删除。
在您的情况下,您在self
创建的异步任务的关闭中创建了对DispatchQueue.main.asyncAfter
的强引用。
您需要告诉编译器此引用是weak
或unowned
(有关详细信息,请参阅附件链接。),这将使self
的实例甚至被取消初始化虽然你从封闭中引用了self
。
weak
关键字可用于您希望关闭运行并执行不需要引用self
unowned
关键字可用于您不希望在没有self
引用的情况下运行闭包的情况。
在闭包中获取自我的weak
或unowned
参考可以像下面的示例一样实现:
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
[weak self] in
self?.doSomething()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
[unowned self] in
self.doSomething()
}
随意加入并改进这个答案:)
答案 1 :(得分:4)
您可以使用此代码块安排Timer
let timer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) { [weak self] timer in
self?.doSomething()
}
按住计时器并在popViewController
之前取消它:
timer.invalidate()
请注意我放在那里的[weak self]
和self?.domeSomething()
以避免对viewcontroller的硬引用,并阅读Laffen关于此的更详细的答案。