Начнем с примера с детской площадки.
Пример 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()
Выход
TestClass1 init is called!
TestClass1 deinit is called!
Пример 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()
Выход
TestClass1 init is called!
func1 is called!
Моя проблема в том, что метод deinit()
никогда не вызывается в примере 2. Я думаю, что есть цикл сохранения, но я не знаю, как это исправить.
Я нашел этот пример и этот SO сообщение, но я не могу реализовать его в своем примере кода.
я отредактировал заголовок
Вы уже связались с stackoverflow.com/a/28138300/1187415, в вашем случае это будет что-то вроде self.funcPointer = { [unowned self] in self.func1() }
Кстати, не проверяйте это на игровой площадке: stackoverflow.com/questions/24363384/…
Это прекрасный пример, когда понятие «закрытие является указателем на функцию» (из вашего предыдущего вопроса) полностью разрушается. В этом контексте замыкание — это выделенный в куче (и ARCed) объект, который хранит строгую ссылку на self
(вызывая сильный цикл сохранения, поддерживающий self
), в дополнение к указателю на реализацию функции.
Чтобы исправить это, вы должны вызвать func1 через weak self.
internal init() {
self.funcPointer = { [weak self] in
self?.func1()
}
print("TestClass1 init is called!")
}
Таким образом, вы можете предотвратить циклы сохранения.
Что происходит в данный момент, так это то, что вы назначаете функцию экземпляра своему свойству экземпляра, которое теперь имеет сильную ссылку на вашу функцию.
Надеюсь это поможет.
Вопрос — как и предыдущий — не особо связан со Swift 5