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

标签 methods closures swift3 capture-list reference-cycle

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

如何删除最后两种情况下的引用循环?

仅使用带有闭包的捕获列表创建和避免强引用循环的示例

internal class ClosureClass {
    internal let p1: String
    internal lazy var p2: () -> String = {
        [unowned self] // if you comment this out there is a strong reference cycle
        () -> String in
        return self.p1
    }

    internal init() {
        self.p1 = "Default value of ClosureClass"
    }

    deinit {
        print("Object with property '\(self.p1)' is being deinitialized")
    }
}
print("Test 'Closure with strong reference to self':")
var cc: ClosureClass? = ClosureClass.init()
cc!.p2() // lazy need to call it once, else it will not be initiliazed
cc = nil

使用方法闭包创建强引用循环的示例

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

使用 extern 方法设置闭包创建强引用循环的示例

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

输出

Test 'Closure with strong reference to self':

Object with property 'Default value of ClosureClass' is being deinitialized

Test 'Set closure with method intern':

Test 'Set closure with method extern':

最佳答案

self.method 只是一个创建闭包的语法糖(默认捕获模式,功能强大):{ () in self.method() }。如果您想使用显式捕获列表,请不要使用语法糖——显式创建一个闭包(这就是它的作用):

{ [unowned self] () in self.method() }

关于methods - 如何从方法的闭包中删除强引用循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41468922/

相关文章:

ios - 闭包中的 Inout 参数(Swift)

Javascript - 命名空间与闭包之间的区别?

swift - 快速使用数组从 FMDB 中删除数据

ios - 异构集合文字只能推断为 '[String : Any]' ;如果这是有意的,请添加显式类型注释

ios - 如何在Swift 3中识别editingStyle中的.delete以删除tableview中的单元格

api - 使用 GetterUtils 和 ParamUtils 的区别

c# - ref 和 out 值类型变量

java - 访问封闭类或父类的方法的一般方法

javascript - 在 ReactJS 中创建 Closure 或 IIFE 来处理 onclick 事件的正确方法是什么

带有 optional 和 &block 参数的 Ruby 方法