dispatch_after是在内存中持久化视图控制器

时间:2015-03-16 15:37:47

标签: ios objective-c swift memory dispatch

我有这段代码,它会在延迟后运行一段代码。

public func delay(delay:Double, closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}

问题是使用延迟功能的视图控制器即使在解雇后仍然存在。删除代码后,它就会变为零。

我需要知道如何有一个像这样的延迟函数,但它不会持久存在它被调用的对象,而是在它不再存在的情况下不会调用该块。 / p>

这是在Swift中,但Objective-C中的回复完全受到赞赏。

3 个答案:

答案 0 :(得分:3)

正如其他人所指出的那样,问题在于您可能正在从视图控制器调用此函数,但是引用了self,它捕获了该视图控制器并保留了对它的强引用。

所以,假设您从视图控制器类中执行了类似的操作:

delay(5) {
    self.label.hidden = true
    return
}

您可以将其替换为明确表示应保持weak self {/ 1}}的引用的内容:

delay(5) { [weak self] in
    self?.label.hidden = true
    return
}

注意,当我使用它时,我不得不打开可选的self。在这个例子中,我使用了可选的链接来确保在调用闭包时selfnil时优雅地失败。

答案 1 :(得分:1)

如果你在闭包中使用ViewController,那么这是正常行为。

答案 2 :(得分:0)

问题可能是你在关闭时引用self。当你这样做时,该块保持对对象的强引用

如果对象也保持对块/闭包的强引用,那么就会得到一个保留周期。

但是,在您的情况下,只有在dispatch_after()激活时才会保留块/闭包。 (我相信对块/闭包的强引用由调度队列保存,并在任务完成并从队列中删除后释放。)