При добавлении подпредставления кажется, что происходит утечка контроллера представления.
Почему следующая надпись "Что"
import UIKit
final class ViewController: UIViewController {
private lazy var mySwitch: UISwitch = {
let mySwitch = UISwitch()
mySwitch.tintColor = .blue
return mySwitch
}()
func setup() {
view.addSubview(mySwitch)
}
@objc func switchChangedState() {
}
deinit {
print("what")
}
}
var controller: ViewController? = ViewController()
controller = nil
Но следующее не
var controller: ViewController? = ViewController()
controller?.setup()
controller = nil
Редактировать: добавление GIF
Xcode версии 9.4.1 (9F2000)
Привет, @TomSchulz. Пишу финал по привычке. В данном конкретном примере это не нужно. При этом я бы порекомендовал добавить final, как привычку, пока вы не будете готовы поддерживать подклассы.
Не согласен. В любом случае, вы не можете отправить файл заголовка и библиотеку. Если кто-то хочет, чтобы что-то не было окончательным, они просто редактируют ваш код. «Поддержка подкласса»; язык поддерживает создание подклассов.
@TomSchulz, я не понимаю, что вы имеете в виду под «отправкой файла заголовка и библиотеки» или «просто отредактируйте свой код».
@TomShulz Я рекомендую добавить final, если вы не готовы поддерживать подклассы. Конечно, вы и другие можете изменить эту идею в будущем. Измените его, когда будете готовы создать подкласс. Кроме того, добавление final - это улучшение производительности. developer.apple.com/swift/blog/?id=27
Я имею в виду, что тот, кто будет работать с вашим кодом, не будет работать с C dot h fle и библиотекой компиляции (например, lib.a), и если они хотят создать подкласс, все, что нужно сделать другому программисту, это отредактировать ваше 'final' ключевое слово и он уехал на скачки. OTOH, я не знал, что final был быстрее, хотя мне интересно, сколько сэкономлено.
Если кто-то попытается создать подкласс окончательного класса, хотя этого не следует делать, компилятор предотвратит успешную сборку. Это полезно. Если другой разработчик хочет создать подкласс класса, который объявлен как final, то, вероятно, этот другой разработчик тщательно изучил этот класс и счел его подходящим для создания подкласса. Или внес в класс необходимые изменения, чтобы можно было безопасно удалить final. Если вы не доверяете этому другому разработчику, вам следует исключить его или ее из команды.
Ваш код хорош. controller?.setup()
не вызовет утечки. Убедитесь, что код в тестовом примере 2 действительно вызван или нет. (Не называйте "что" напечатано)
Я поддерживаю это - здесь нет цикла сохранения. Когда я создаю и запускаю ваш код, в обоих случаях вызывается деинициализатор.
Привет @PeteMorris. Я согласен, код определенно предполагает, что здесь нет цикла сохранения, но поведение, которое я вижу, говорит об обратном. Добавили гифку для демонстрации.
Привет, @YunCHEN добавил гифку к посту.
@Jonesy Это как-то связано с игровой площадкой, с вашим кодом все в порядке. Возможно, это ошибка, или, возможно, игровая площадка по какой-то причине сохранила ваш контроллер. Если вы запустите тот же самый код в реальном проекте Xcode, деинициализатор обязательно будет запущен в обоих случаях: imgur.com/a/QkLn6Q3
Спасибо, @PeteMorris примет, если вы сделаете официальный ответ
@Jonesy, как сказал Пит Моррис, в PlayGround могут быть некоторые ошибки, из-за которых ваш контроллер не работает. Чтобы доказать это, добавьте controller = ViewController()
дважды в конце (после controller = nil
), вы получите напечатанное «что», что означает, что прежний контроллер действительно выпущен. Так что это не цикл сохранения.
В вашем коде нет ничего плохого. Здесь нет цикла сохранения.
Проблема, похоже, связана с детской площадкой. Это может быть ошибка, или игровая площадка может по какой-то причине сохранить ваш контроллер представления.
Если вы выполняете свой код в реальном проекте Xcode (либо в симуляторе iOS, либо на устройстве), инициализатор выполняется в обоих случаях:
Почему окончательный?