暂时在街区捕获自己

时间:2015-01-04 23:29:16

标签: swift

在编译程序时出现运行时错误,有目的地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()
}

1 个答案:

答案 0 :(得分:1)

  

请确认我不应在此使用[unowned self]

仅仅因为匿名函数提到self而没有必要关心内存管理。

如果提及self的匿名函数将成为self然后的属性,则会有保留周期和潜在的内存泄漏,您应该关心自己内存管理。通过实施deinit来记录,您可以轻松查看是否有内存泄漏;如果它没有记录,你希望这个对象被销毁,它就会泄漏。如果泄漏,您可以尝试使用[weak self],而不是[unowned self]unowned更方便,但只能在非常有限的情况下使用。

但是,我没有看到任何证据表明将保留回调的对象与其中称为self的对象相同。它看起来更像是相反:你似乎在每个匿名函数上使用[unowned self],显然对你正在做的事情没有丝毫的了解。那是非常危险的。除非必须,否则不应干扰内存管理,除非您知道如何操作。我的建议是,首先删除代码中的每个unowned。然后实现deinit并查看是否有任何实际泄漏的对象。我打赌你没有。