2

My goal is to create a class which contains an array. The elements of the array will be the methods of the same class. like:

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

When I call the executeAll() it works fine and I achieve my expected result:

var myObject = MyClass()
myObject.executeAll()

The problem is, it create reference cycle. Instance of MyClass holds the array functions and functions array holds self. So If I write below code:

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

It will not call deinit method because of this strong reference cycle. How can I add method pointers to array as weak self? I don't want to use a local copy of functions in executeAll method.

1
  • why not just declare your functions variable as optional, and simply set it to nil after the execution since you want it to be deallocated after. Commented Mar 7, 2019 at 8:12

2 Answers 2

2

If the method list is independent of the particular instance then you can make it a type property and avoid the reference cycle:

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

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

   // ...
}

The array elements are “curried functions” of the type

(MyClass) -> () -> ()

compare Instance Methods are “Curried” Functions in Swift.

Sign up to request clarification or add additional context in comments.

Comments

-1

Try this way,

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

5 Comments

I am afraid that this would not solve the retain cycle problem. If you set myObject = nil after calling myUnowned.value.executeAll() the the object is not deallocated. And if you set myObject = nil before calling myUnowned.value.executeAll() then you'll get a crash.
Are you doing that on playground ?
No, in a compiled project. A Playground is not good for testing object (de)allocation.
i know, was making sure you're not
Try let myUnowned = Unowned(MyClass()); myUnowned.value.executeAll() ... 💣

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.