Avoid retain cycles for function pointers in Swift

断了今生、忘了曾经 提交于 2019-12-24 18:33:52

问题


Let's start with this playground example

Example 1

import UIKit

internal final class TestClass1 {
    var testVar: Int = 1

    internal init() {
        print("TestClass1 init is called!")
    }

    deinit {
        print("TestClass1 deinit is called!")
    }

    internal func func1() {
        print("func1 is called!")
    }
}

internal final class TestClass2 {
    init() {
        let testClass1: TestClass1 = TestClass1()
        testClass1.testVar = 10
    }
}

var testClass2: TestClass2 = TestClass2()

Output

TestClass1 init is called!

TestClass1 deinit is called!

Example 2

import UIKit

internal final class TestClass1 {
    internal final var funcPointer: (() -> ())!

    internal init() {
        self.funcPointer = self.func1
        print("TestClass1 init is called!")
    }

    deinit {
        print("TestClass1 deinit is called!")
    }

    internal func func1() {
        print("func1 is called!")
    }
}

internal final class TestClass2 {
    init() {
        let testClass1: TestClass1 = TestClass1()
        testClass1.funcPointer()
    }
}

var testClass2: TestClass2 = TestClass2()

Output

TestClass1 init is called!

func1 is called!

My problem is, that the deinit() method is never called in example 2. I think there is a retain cycle but I don't know how to fix it.

I found this example and this SO post but I can't implement it in my example code.


回答1:


To fix it, you have to call the func1 through weak self.

internal init() {
    self.funcPointer = { [weak self] in
        self?.func1()
    }
    print("TestClass1 init is called!")
}

This way you can prevent retain cycles.

What happens at the moment is that you are assigning an instance function to your instance property who now has a strong reference to your function.

Hope this helps.



来源:https://stackoverflow.com/questions/56348309/avoid-retain-cycles-for-function-pointers-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!