暂时将自己捕获在块中

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 并查看是否有任何实际泄漏的对象。我打赌你不会。