dispatch_after 正在内存中持久化视图控制器
dispatch_after is persisting view controller in memory
我有这段代码,它在延迟后运行一段代码。
public func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
问题是使用延迟功能的视图控制器即使在关闭后仍然存在。删除代码后,它应该变成零。
我需要知道如何拥有像这样的延迟函数,但它不会保留调用它的对象,而是不会调用该块,以防它不再存在.
这是在 Swift 中,但非常感谢 Objective-C 中的回复。
如果您在闭包中使用 ViewController 则这是正常行为。
问题很可能是您在闭包中引用了 self。当你这样做时,块会保持对对象的强引用
如果该对象还保持对 block/closure 的强引用,那么您将获得一个保留周期。
但是,在您的情况下,block/closure 应该只保留到 dispatch_after() 调用触发。 (我相信对 block/closure 的强引用由调度队列持有,并在任务完成并从队列中删除后释放。)
正如其他人指出的那样,问题在于您可能是从视图控制器调用此函数,但有对 self
的引用,它捕获该视图控制器并保持对它的强引用.
那么,假设您在视图控制器中做了类似的事情 class:
delay(5) {
self.label.hidden = true
return
}
您可以将其替换为明确表示应保持 weak
对 self
的引用:
delay(5) { [weak self] in
self?.label.hidden = true
return
}
注意,当我使用它时,我必须打开可选的 self
。在此示例中,如果 self
在调用闭包时 nil
时,我使用可选链接来确保正常失败。
我有这段代码,它在延迟后运行一段代码。
public func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
问题是使用延迟功能的视图控制器即使在关闭后仍然存在。删除代码后,它应该变成零。
我需要知道如何拥有像这样的延迟函数,但它不会保留调用它的对象,而是不会调用该块,以防它不再存在.
这是在 Swift 中,但非常感谢 Objective-C 中的回复。
如果您在闭包中使用 ViewController 则这是正常行为。
问题很可能是您在闭包中引用了 self。当你这样做时,块会保持对对象的强引用
如果该对象还保持对 block/closure 的强引用,那么您将获得一个保留周期。
但是,在您的情况下,block/closure 应该只保留到 dispatch_after() 调用触发。 (我相信对 block/closure 的强引用由调度队列持有,并在任务完成并从队列中删除后释放。)
正如其他人指出的那样,问题在于您可能是从视图控制器调用此函数,但有对 self
的引用,它捕获该视图控制器并保持对它的强引用.
那么,假设您在视图控制器中做了类似的事情 class:
delay(5) {
self.label.hidden = true
return
}
您可以将其替换为明确表示应保持 weak
对 self
的引用:
delay(5) { [weak self] in
self?.label.hidden = true
return
}
注意,当我使用它时,我必须打开可选的 self
。在此示例中,如果 self
在调用闭包时 nil
时,我使用可选链接来确保正常失败。