Массив методов в быстром без эталонного цикла - PullRequest
2 голосов
/ 07 марта 2019

Моя цель - создать класс, который содержит массив.Элементами массива будут методы одного и того же класса.например:

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.

Ответы [ 2 ]

2 голосов
/ 07 марта 2019

Если список методов не зависит от конкретного экземпляра, вы можете сделать его типом свойства и избежать цикла ссылок:

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

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

   // ...
}

Элементы массива являются «функциями карри» типа

(MyClass) -> () -> ()

сравнить Методы экземпляра являются «каррированными» функциями в Swift .

0 голосов
/ 07 марта 2019

Попробуйте так,

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()
...