【问题标题】:dispatch_after is persisting view controller in memorydispatch_after 在内存中持久化视图控制器
【发布时间】:2015-05-18 19:23:18
【问题描述】:

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

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

问题是使用延迟功能的视图控制器即使在关闭后仍然存在。删除代码后,它就变成了 nil。

我需要知道如何拥有一个像这样的延迟函数,但它不会持久化调用它的对象,而是不会调用块,以防它不再存在。

这是在 Swift 中,但完全感谢 Objective-C 中的回复。

【问题讨论】:

  • 向我们展示您的closure 的代码。通常,您必须使用 weak 引用来解决保留周期问题。

标签: ios objective-c swift memory dispatch


【解决方案1】:

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

所以,假设您在视图控制器类中做了这样的事情:

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

您可以将其替换为明确表示应保持weakself 的引用:

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

注意,当我使用它时,我必须解开可选的self。在这个例子中,我使用了可选链来确保在调用闭包时 selfnil 时会正常失败。

【讨论】:

    【解决方案2】:

    问题很可能是您在闭包中引用了 self。当你这样做时,块保持对对象的强引用

    如果对象还保持对块/闭包的强引用,那么您将获得一个保留周期。

    但是,在您的情况下,块/闭包应该只保留到 dispatch_after() 调用触发。 (我相信对阻塞/闭包的强引用由调度队列持有,并在任务完成并从队列中删除后释放。)

    【讨论】:

      【解决方案3】:

      如果您在关闭时使用 ViewController,那么这是正常行为。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-19
        • 1970-01-01
        • 2014-02-22
        • 1970-01-01
        • 2016-08-23
        • 1970-01-01
        • 2014-08-04
        • 1970-01-01
        相关资源
        最近更新 更多