Ответ 1
Я использовал:
convenience init() {
self.init(nibName:nil, bundle:nil)
}
Некоторые люди предложили:
convenience init(){
self.init()
}
Но это дает вам бесконечный цикл.
Я не могу добавить метод init к следующему классу UIViewController. Мне нужно написать код в методе init. Должен ли я писать метод init (coder)? Даже когда я добавляю методы кодера и декодера, я все равно получаю ошибки. Я также попытался использовать метод init без каких-либо параметров, но это также не работает.
class ViewController: UIViewController {
var tap: UITapGestureRecognizer?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nil, bundle: nil)
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
...
...
}
Если я вызываю метод super.init() без параметров, ошибка "Должен вызывать назначенный инициализатор суперкласса", и если я передаю параметр nib и bundle, тогда ошибка "Требуется инициализатор инициализации (кодера)".
Даже когда я добавляю init (coder) и init (декодер), он не работает.
Я использовал:
convenience init() {
self.init(nibName:nil, bundle:nil)
}
Некоторые люди предложили:
convenience init(){
self.init()
}
Но это дает вам бесконечный цикл.
Все эти ответы являются полу ответами. Некоторые люди испытывают бесконечные циклы в связанных сообщениях, потому что они только добавляют convenience init()
(он рекурсивно вызывает себя, если вы не предоставляете отдельный метод init()
для его вызова), в то время как другие люди пренебрегают расширением суперкласса, Этот формат объединяет все решения, чтобы полностью удовлетворить проблему.
// This allows you to initialise your custom UIViewController without a nib or bundle.
convenience init() {
self.init(nibName:nil, bundle:nil)
}
// This extends the superclass.
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
// This is also necessary when extending the superclass.
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented") // or see Roman Sausarnes answer
}
Изменить: Кроме того, если вы хотите инициализировать любые свойства класса с помощью параметров, переданных в ваш метод convenience init()
, без использования всех переопределенных методов init()
, вы можете установить все эти свойства как неявно развернутые варианты, которые являются образцом используемым самими Apple.
Вам необходимо переопределить инициализатор init(nibName:bundle:)
, предоставить требуемый инициализатор init(coder:)
и инициализировать tap
в обоих из них:
class ViewController: UIViewController {
var tap: UITapGestureRecognizer?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
print("init nibName style")
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
// note slightly new syntax for 2017
required init?(coder aDecoder: NSCoder) {
print("init coder style")
super.init(coder: aDecoder)
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
...
...
}
Кроме того, при вызове инициализатора суперкласса убедитесь, что вы не просто передали nil
для nibName
и bundle
. Вы должны отказаться от всего, что было передано.
Обратите внимание, что "удобный метод инициализации", упомянутый в некоторых ответах, имеет значение только в том случае, если вы на самом деле "вручную" сами инициализируете контроллер представления. (Есть очень немного ситуаций, когда вы могли бы сделать это.) Если вы хотите "сделать что-то во время обычной инициализации" - например, создать распознаватель жестов или просто инициализировать некоторые переменные - единственно возможное решение - это точно тот, который дан в этом ответе.
Вместо этого вы можете просто создать инициализатор удобства, инициализаторы удобства не переопределяют init(), а просто называют его упростить процесс.
class ViewController: UIViewController {
var tap: UITapGestureRecognizer?
convenience init(){
self.init()
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
}
Думаю, вам нужно добавить
required init(coder aDecoder: NSCoder) {
print("init coder")
super.init(coder: aDecoder)
}
или
convenience init() {
self.init()
}
Вы также должны написать init. Не удаляйте его.
var tap: UITapGestureRecognizer?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nil, bundle: nil)
}
Надеюсь, что это поможет
Я столкнулся с этим вопросом о тебе, который просил долгий путь назад. Но никто не дал основополагающего ответа на этот вопрос. Это основной в Swift, который: - Подкласс должен инициализировать свои переменные перед завершением инициализации суперкласса.
Следовательно, как Ankit Goel упоминается сбой: - "Должен вызывать назначенный инициализатор суперкласса"
Следовательно, обновленный код будет: -
class ViewController: UIViewController {
var tap: UITapGestureRecognizer?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
print("init nibName style")
self.tap = nil
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:")))
}
required init?(coder aDecoder: NSCoder) {
print("init coder style")
self.tap = nil
super.init(coder: aDecoder)
tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:")))
}}