Можно ли переопределить deinit в Swift?
При создании подкласса из другого класса требуется override
init()
функция, но вы не можете переопределить deinit
"Функция".
Возможно ли это в Swift?
Вот пример
class Foo {
init(){
print("Foo created")
}
deinit {
print("Foo gone")
}
}
class Bar: Foo {
override init(){
print("Bar created")
}
//Is not overwritten here
deinit {
print("Bar gone")
}
}
Внутри пример viewcontroller
override func viewDidLoad() {
super.viewDidLoad()
var f: Foo?
f = Foo()
f = Bar()
f = nil
}
Выход
Foo created //Foo object initialised - Foo init() called
Foo created //Foo init() called before calling Bar init()? no call to superclass though..
Bar created //Bar object initialised - Bar init() called
Foo gone //Foo deinit called as Foo instance replaced by Bar instance
Bar gone //Bar deinit called as Bar instance holds no references and is destroyed
Foo gone //Foo deinit called again as part of Bar object destruction?
Добавить к моему первоначальному вопросу о расширении deinit
:
В примере кода кажется, что переопределение init()
вызывает вызов init()
функция суперкласса. Это то, что происходит?
Такое же поведение происходит, когда Bar
экземпляр деинициализирован. Это также то, что здесь происходит?
1 ответ
deinit
это не обычный метод, его нельзя переопределить. Каждый экземпляр имеет один независимый deinit
обработчик для своего класса и всех его суперклассов.
Деинициализаторы вызываются автоматически, непосредственно перед освобождением экземпляра. Вы не можете вызывать деинициализатор самостоятельно. Деинициализаторы суперкласса наследуются их подклассами, и деинициализатор суперкласса вызывается автоматически в конце реализации деинициализатора подкласса. Деинициализаторы суперкласса всегда вызываются, даже если подкласс не обеспечивает свой собственный деинициализатор.
Не должно быть абсолютно никаких оснований для того, чтобы что-то менять в своем суперклассе. deinit
,
Почему это отличается от init
? В инициализаторах вам нужно передать параметры, вам также нужно контролировать порядок выполнения (некоторый код перед super.init(...)
код после super.init(...)
). Деинициализация - это автоматический процесс с определенным порядком выполнения. Переопределение может привести только к ненужным проблемам.