2014-06-06 29 views
3

我正在浏览文档(有关“自动引用计数”一节“关闭的强参考周期”一节),并且在定义类时,我似乎无法找出案例,我应该在一个属性的闭包中保留对self(该类的实例)的强烈参考。捕获列表似乎总是避免内存泄漏的最佳解决方案,我真的无法想象任何应该保持强大参考周期的情况。Swift中关闭的强参考周期

这里有例子,该文档提供了:

class HTMLElement { 

    let name: String 
    let text: String? 

    // Without Capture List 
    @lazy var asHTML:() -> String = { 
     if let text = self.text { 
      return "<\(self.name)>\(text)</\(self.name)>" 
     } else { 
      return "<\(self.name) />" 
     } 
    } 

    init(name: String, text: String? = nil) { 
     self.name = name 
     self.text = text 
    } 

    deinit { 
     println("\(name) is being deinitialized") 
    } 

} 

class HTMLElement { 

    let name: String 
    let text: String? 

    // With Capture List 
    @lazy var asHTML:() -> String = { 
     [unowned self] in 
     if let text = self.text { 
      return "<\(self.name)>\(text)</\(self.name)>" 
     } else { 
      return "<\(self.name) />" 
     } 
    } 

    init(name: String, text: String? = nil) { 
     self.name = name 
     self.text = text 
    } 

    deinit { 
     println("\(name) is being deinitialized") 
    } 

} 
+0

准确地说你的问题是什么? – holex

+0

“我真的无法想象任何情况下我应该保持一个强大的参考周期” - >有没有? – Giovanni

+0

这是一个未被优化的代码要避免的例子。 – Giovanni

回答

5

你需要保持很强的参考自我,如果你正在创建一个闭合由一个对象或函数来执行他的一生可能不符合自己的生活。

例如:

class A { 
    func do() { 
     dispatch_async(dispatch_get_global_queue(0, 0)) { 
      println("I printed \(self) some time in the future.") 
     } 
    } 
} 

var a : A? = A() 
a.do() 
a = nil // <<< 

在箭头的主要功能身体会释放其最后一个引用A的新创建的实例,但调度队列需要保持它保持直到闭合完成执行。

+0

谢谢你。现在对我来说很有意义。为什么你认为对自我的强烈指涉是“默认”行为?这似乎不是一个记忆友好的行为。谢谢! – Giovanni

+0

使它成为一个强有力的参考是默认的最安全行为,因为这可以保证在执行闭包时对象仍然存在 - 弱引用意味着它可能突然变为零,而无主引用意味着它可能指向无效数据。另外,它可以(可以说)更常见的用作外部方法的参数(例如对于某些未来的外部事件的回调),而不是将它们作为创建闭包的类的属性来存储它们。在这些情况下,将“自我”作为强有力的参照往往是完全合理的行为。 –