如何从方法的闭包中删除强参考循环? [英] How to remove strong reference cycle from closure from method?

查看:122
本文介绍了如何从方法的闭包中删除强参考循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这里,我有一些关于封闭强参考周期的示例. 如果将闭包分配给存储的属性,则可以使用闭包捕获列表将捕获的引用设为无主/弱. 但是,如果我将方法分配给存储属性闭包或将方法分配给外部作用域中的闭包,则无法使用捕获列表.

Here I have some examples for closure strong reference cycles. If I assign a closure to a stored property, I can use a closure capture list to make the captured reference unowned/weak. But if I assign a method to a stored property closure or assign the method to a closure in the outer scope I can not use a capture list.

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':

具有"closureClass的默认值"属性的对象正在被取消初始化

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

测试使用方法实习生设置闭合":

Test 'Set closure with method intern':

测试使用方法extern设置闭包":

Test 'Set closure with method extern':

推荐答案

self.method只是用于创建闭包(具有默认捕获模式,即强)的语法糖:{ () in self.method() }.如果要使用显式捕获列表,请不要使用语法糖-显式创建一个闭包(无论如何,它都是这样做的):

self.method is just a syntactic sugar for creating a closure (with the default capture mode, which is strong): { () in self.method() }. If you want to use an explicit capture list, don't use the syntactic sugar -- create a closure (which is what it does anyway) explicitly:

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

这篇关于如何从方法的闭包中删除强参考循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆