【问题标题】:Array of methods in swift without reference cycle没有参考周期的快速方法数组
【发布时间】:2019-07-29 00:13:17
【问题描述】:

我的目标是创建一个包含数组的类。数组的元素将是同一类的方法。喜欢:

class MyClass {
    lazy var functions = [self.myFirstMethod, self.mySecondMethod]

    deinit {
        print("Deinit")
    }

    func myFirstMethod() {
        // Do Something
    }

    func mySecondMethod() {
        // Do Something
    }

    func executeAll() {
        for f in functions {
            f()
        }
    }
}

当我调用 executeAll() 时,它工作正常,我达到了预期的结果:

var myObject = MyClass()
myObject.executeAll()

问题是,它创建了引用循环。 MyClass 的实例包含数组 functions 和 functions 数组包含 self。所以如果我写下面的代码:

var myObject: MyClass? = MyClass()
myObject.executeAll()
myObject = nil

由于这个强引用循环,它不会调用deinit 方法。 如何将数组的方法指针添加为weak self?我不想在 executeAll 方法中使用函数的本地副本。

【问题讨论】:

  • 为什么不将 functions 变量声明为可选变量,并在执行后将其设置为 nil,因为您希望在之后释放它。

标签: arrays swift function-pointers swift4.2


【解决方案1】:

如果方法列表独立于特定实例,则可以将其设为类型属性并避免引用循环:

class MyClass {
    static let functions = [myFirstMethod, mySecondMethod]

    func executeAll() {
        for f in MyClass.functions {
            f(self)()
        }
    }

   // ...
}

数组元素是类型的“柯里化函数”

(MyClass) -> () -> ()

比较Instance Methods are “Curried” Functions in Swift。

【讨论】:

    【解决方案2】:

    试试这个方法,

    class Unowned<T: AnyObject> {
        unowned let value: T
        init(_ value: T) {
            self.value = value
        }
    }
    
    var myObject: MyClass = MyClass()
    var myUnowned = Unowned(myObject)
    myUnowned.value.executeAll()
    

    【讨论】:

    • 恐怕这并不能解决保留周期问题。如果您在调用myUnowned.value.executeAll() 之后设置myObject = nil ,则不会释放对象。如果你设置myObject = nil 之前 调用myUnowned.value.executeAll() 那么你会遇到崩溃。
    • 你在操场上这样做吗?
    • 否,在已编译的项目中。 Playground 不适合测试对象(取消)分配。
    • 我知道,确保你不是
    • 试试let myUnowned = Unowned(MyClass()); myUnowned.value.executeAll() ...?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 2016-02-13
    • 2019-01-20
    • 1970-01-01
    相关资源
    最近更新 更多