如何从闭包中移除强引用循环



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

在最后两种情况下,我可以做些什么来删除引用循环?

创建和避免强引用循环的示例,使用只包含

闭包的捕获列表
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

创建强引用循环的示例,设置了from from 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':

属性为' ClosureClass的默认值'的对象正在被取消初始化

Test 'Set closure with method intern':

测试'Set closure with method extern':

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

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

相关内容

  • 没有找到相关文章

最新更新