如何退出" DispatchQueue.main.asyncAfter"在斯威夫特

时间:2018-04-18 07:49:38

标签: ios swift xcode

我想退出" 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()。 我该怎么办?

2 个答案:

答案 0 :(得分:4)

在Swift中我们有一个名为ARC(Automatic Reference Counting)的东西。 ARC将确保任何具有至少一个强引用的对象不会从内存中删除。

在您的情况下,您在self创建的异步任务的关闭中创建了对DispatchQueue.main.asyncAfter的强引用。

您需要告诉编译器此引用是weakunowned(有关详细信息,请参阅附件链接。),这将使self的实例甚至被取消初始化虽然你从封闭中引用了self

weak关键字可用于您希望关闭运行并执行不需要引用self

的操作的情况

unowned关键字可用于您不希望在没有self引用的情况下运行闭包的情况。

在闭包中获取自我的weakunowned参考可以像下面的示例一样实现:

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关于此的更详细的答案。