Methods 如何从方法的闭包中删除强引用循环?
这里我有一些闭包强引用循环的例子。 如果我将闭包分配给存储的属性,我可以使用闭包捕获列表使捕获的引用无主/弱。 但是,如果我将一个方法分配给存储属性闭包,或者将该方法分配给外部作用域中的闭包,我就不能使用捕获列表 在最后两种情况下,如何删除参考循环? 创建和避免强引用循环的示例,仅使用带闭包的捕获列表 使用闭包from方法创建强引用循环的示例 创建强引用循环的示例,其中设置了extern中方法的闭包 输出 测试“强引用自身的闭合”: 正在取消初始化属性为“ClosureClass的默认值”的对象 测试“使用内部方法设置闭合”: 测试“使用外部方法设置闭包”:Methods 如何从方法的闭包中删除强引用循环?,methods,closures,swift3,capture-list,reference-cycle,Methods,Closures,Swift3,Capture List,Reference Cycle,这里我有一些闭包强引用循环的例子。 如果我将闭包分配给存储的属性,我可以使用闭包捕获列表使捕获的引用无主/弱。 但是,如果我将一个方法分配给存储属性闭包,或者将该方法分配给外部作用域中的闭包,我就不能使用捕获列表 在最后两种情况下,如何删除参考循环? 创建和避免强引用循环的示例,仅使用带闭包的捕获列表 使用闭包from方法创建强引用循环的示例 创建强引用循环的示例,其中设置了extern中方法的闭包 输出 测试“强引用自身的闭合”: 正在取消初始化属性为“ClosureClass的默认值”的对象
self.method
只是创建闭包的一种语法糖(使用默认的捕获模式,这种模式很强):{self.method()中的()
。如果要使用显式捕获列表,请不要使用语法糖——显式创建一个闭包(不管怎样,它就是这样做的):
{ [unowned self] () in self.method() }
无关:您可以使用
self.method
而不是method(self)
。另外,您不需要将所有内容都注释为内部
,这是默认值。@Hamish Oh好笑,如果编写self,Xcode 8不建议method
。
在属性闭包的情况下,缺少特性或bug,但在编写method
时,它给了我方法(self)
的建议。谢谢你指出。有趣的是,method
对于一个属性来说是不够的,但是对于外部范围内的一个变量来说就足够了。需要self.method
而不仅仅是method
是lazy
属性的一个怪癖–它们需要显式地使用self.
,例如,哦,好吧,现在我明白了self.method
或method(self)
返回一个闭包,其中代码位于方法定义的大括号中。因此,如果您编写self.method()
,您并不是在避免使用self.method
创建闭包,只是在之后执行它,然后将它打包到另一个闭包中,以获得无主的/弱的语义。@Hamish:我不知道编译器是如何实现它们的。但从语言的角度来看,它们似乎在语义上是等价的。
internal class MethodToClosureClass {
internal let p1: String
internal lazy var p2: () -> String = method(self) // Why not self.method ? Will create a strong reference cycle, but I can not set the reference to weak or unowned like in closures with the closure capture list
internal init() {
self.p1 = "Default value of MethodToClosureClass"
}
internal func method() -> String {
// [unowned self] in
return self.p1
}
deinit {
print("Object with property '\(self.p1)' is being deinitialized")
}
}
print("Test 'Set closure with method intern':")
var m2cc: MethodToClosureClass? = MethodToClosureClass.init()
m2cc!.p2() // lazy need to call it once, else it will not be initiliazed
m2cc = nil
internal class MethodClass {
internal let p1: String
internal var p2: () -> String = {
return ""
}
internal init() {
self.p1 = "Default value of MethodClass"
}
internal func method() -> String {
// [unowned self] in
return self.p1
}
deinit {
print("Object with property '\(self.p1)' is being deinitialized")
}
}
print("Test 'Set closure with method extern':")
var mc: MethodClass? = MethodClass.init()
var method: () -> String = mc!.method // will create a strong reference
mc!.p2 = method
mc = nil
{ [unowned self] () in self.method() }