Methods 如何从方法的闭包中删除强引用循环?

Methods 如何从方法的闭包中删除强引用循环?,methods,closures,swift3,capture-list,reference-cycle,Methods,Closures,Swift3,Capture List,Reference Cycle,这里我有一些闭包强引用循环的例子。 如果我将闭包分配给存储的属性,我可以使用闭包捕获列表使捕获的引用无主/弱。 但是,如果我将一个方法分配给存储属性闭包,或者将该方法分配给外部作用域中的闭包,我就不能使用捕获列表 在最后两种情况下,如何删除参考循环? 创建和避免强引用循环的示例,仅使用带闭包的捕获列表 使用闭包from方法创建强引用循环的示例 创建强引用循环的示例,其中设置了extern中方法的闭包 输出 测试“强引用自身的闭合”: 正在取消初始化属性为“ClosureClass的默认值”的对象

这里我有一些闭包强引用循环的例子。 如果我将闭包分配给存储的属性,我可以使用闭包捕获列表使捕获的引用无主/弱。 但是,如果我将一个方法分配给存储属性闭包,或者将该方法分配给外部作用域中的闭包,我就不能使用捕获列表

在最后两种情况下,如何删除参考循环? 创建和避免强引用循环的示例,仅使用带闭包的捕获列表 使用闭包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() }