在编译程序时出现运行时错误,有目的地SomeObject
的实例化是短暂的,但是块传递会捕获引用,在操场中不起作用但在程序编译和运行时显示错误
目标是暂时保留短生命对象SomeObject
的引用,直到回调完成。
修改 - 如果我在[unowned self]
内发表评论go
它的确有效,因为我相信它会创建一个强大的参考,但希望没有内存泄漏? (无论如何,调用者对象超出了范围)。请确认我不应在此使用[unowned self]
。
import Foundation
class SomeObject {
func go() { //i guess problem is here, it can't find self,
anotherObject.asyncCall({ [unowned self] in //works if i comment this
self.complete()
})
}
func complete() { //can't move this routine inside block, part of parent class api
println("received callback after 5 sec")
}
}
class AnotherObject {
var callback: (() -> ())?
init() {}
func asyncCall(callback: () -> ()) {
self.callback = callback
let delay = 5 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue(), { [unowned self] in
self.callback!()
})
}
}
var anotherObject = AnotherObject() //not global object but permanent lived
for i in 1...3 { //can't change here, it's part of API that instantiates my objects
var instance = SomeObject() //short lived objects
instance.go()
}
答案 0 :(得分:1)
请确认我不应在此使用
[unowned self]
仅仅因为匿名函数提到self
而没有必要关心内存管理。
如果提及self
的匿名函数将成为self
,然后的属性,则会有保留周期和潜在的内存泄漏,您应该关心自己内存管理。通过实施deinit
来记录,您可以轻松查看是否有内存泄漏;如果它没有记录,你希望这个对象被销毁,它就会泄漏。如果泄漏,您可以尝试使用[weak self]
,而不是[unowned self]
。 unowned
更方便,但只能在非常有限的情况下使用。
但是,我没有看到任何证据表明将保留回调的对象与其中称为self
的对象相同。它看起来更像是相反:你似乎在每个匿名函数上使用[unowned self]
,显然对你正在做的事情没有丝毫的了解。那是非常危险的。除非必须,否则不应干扰内存管理,除非您知道如何操作。我的建议是,首先删除代码中的每个unowned
。然后实现deinit
并查看是否有任何实际泄漏的对象。我打赌你没有。