我想在调用deinit时退出“ DispatchQueue.main.asyncAfter”。
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
//...
}
}
Run Code Online (Sandbox Code Playgroud)
当_ = self.navigationController?.popViewController(animated: true)调用ViewController do 和deinit时,首先在ViewController和subView中调用deinit,然后在几分钟后doSomething()调用。我想在doSomething()执行popViewController时停止。我该怎么做?
在Swift中,我们有一个叫做ARC(自动引用计数)的东西。ARC将确保不会从内存中删除至少具有一个强引用的任何对象。
在您的情况下,您将self在结束由创建的异步任务时创建强烈引用DispatchQueue.main.asyncAfter。
您需要告诉编译器此引用为weakor或unowned(请参阅附件链接以获取更多信息。),self即使您self从闭包中引用了它,也可以取消初始化的实例。
该weak关键字可以在你想关闭运行的情况下,使操作使用,不需要为参考self
unowned如果您不希望闭包在不引用的情况下运行闭包,则可以使用该关键字self。
可以在闭包中获取self weak或unowned引用self,如以下示例所示:
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
[weak self] in
self?.doSomething()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
[unowned self] in
self.doSomething()
}
Run Code Online (Sandbox Code Playgroud)
值得一提的是,如果您不使用截止日期,但是.async { ... }直接调用不会导致捕获自身,因此无需定义即可安全地使用它weak/unowned self。
您可以Timer使用此代码块安排
let timer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) { [weak self] timer in
self?.doSomething()
}
Run Code Online (Sandbox Code Playgroud)
按住计时器并在取消之前将其取消,popViewController如下所示:
timer.invalidate()
Run Code Online (Sandbox Code Playgroud)
请注意,我[weak self]在self?.domeSomething()此处放置了和,以避免对视图控制器进行硬引用,并阅读Laffen对此的更详细的答案。