暂时将自己捕获在块中
Capturing self in the block temporarily
编译程序时出现运行时错误,故意 SomeObject
的实例化是短暂的,但传递的块捕获引用,在 playground 中不起作用,但在编译程序时显示错误并运行。
目标是临时保存短暂对象的引用SomeObject
,直到回调完成。
Edit - 如果我在 go
中评论 [unowned self]
它有效,因为我相信它创建了一个强引用,但希望那里没有内存泄漏? ?? (无论如何,调用者对象超出了范围)。请确认我不应该在这里使用 [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()
}
please confirm that I shouldn't use [unowned self]
in here
没有必要仅仅因为匿名函数提到 self
.
就关心内存管理
如果提到 self
的匿名函数将成为 self
的 属性, 那么 你有一个保留周期并且潜在的内存泄漏,您应该关注内存管理。你可以通过实现你的 deinit
来记录,很容易地看到你是否有内存泄漏;如果它在您希望销毁此对象时没有记录,则说明它正在泄漏。如果它正在泄漏,您可以尝试使用 [weak self]
,而不是 [unowned self]
。 unowned
更方便,但只能在非常有限的情况下使用。
但是,我没有看到任何证据表明将保留回调的对象与其中引用的对象相同 self
。在我看来它更像是相反的:你似乎在每个匿名函数上使用 [unowned self]
,显然对你在做什么一无所知。那是极其危险的。你不应该干涉内存管理,除非你不得不这样做,除非你知道如何去做。我的建议是,您首先要删除代码中的每个 unowned
。然后执行 deinit
并查看是否有任何实际泄漏的对象。我打赌你不会。
编译程序时出现运行时错误,故意 SomeObject
的实例化是短暂的,但传递的块捕获引用,在 playground 中不起作用,但在编译程序时显示错误并运行。
目标是临时保存短暂对象的引用SomeObject
,直到回调完成。
Edit - 如果我在 go
中评论 [unowned self]
它有效,因为我相信它创建了一个强引用,但希望那里没有内存泄漏? ?? (无论如何,调用者对象超出了范围)。请确认我不应该在这里使用 [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()
}
please confirm that I shouldn't use
[unowned self]
in here
没有必要仅仅因为匿名函数提到 self
.
如果提到 self
的匿名函数将成为 self
的 属性, 那么 你有一个保留周期并且潜在的内存泄漏,您应该关注内存管理。你可以通过实现你的 deinit
来记录,很容易地看到你是否有内存泄漏;如果它在您希望销毁此对象时没有记录,则说明它正在泄漏。如果它正在泄漏,您可以尝试使用 [weak self]
,而不是 [unowned self]
。 unowned
更方便,但只能在非常有限的情况下使用。
但是,我没有看到任何证据表明将保留回调的对象与其中引用的对象相同 self
。在我看来它更像是相反的:你似乎在每个匿名函数上使用 [unowned self]
,显然对你在做什么一无所知。那是极其危险的。你不应该干涉内存管理,除非你不得不这样做,除非你知道如何去做。我的建议是,您首先要删除代码中的每个 unowned
。然后执行 deinit
并查看是否有任何实际泄漏的对象。我打赌你不会。