2015-07-15 3 views
2

Немного смутитесь относительно назначенных и удобных инициализаторов для UIViewController в Swift 2.0/Xcode 7beta3. Наши UIViewControllers все определены в коде, не существует НибсSwift 2.0 Подкласс подкласса UIViewController и вызванные инициализаторы удобства

класса В настоящее время не наследует от UIViewController, как это

class A : UIViewController { 
    convenience init() { 
     ... 
     self.init(nibName:nil, bundle:nil) 
     ... 
    }  
} 

Тогда класс B наследует от класса A и должны переопределить удобство инициализации и вызвать его, как супер. INIT()

class B : A { 
    convenience init() { 
     super.init() 
     ... 
    }  
} 

компилятор не позволяет это с должно вызвать назначенный инициализатору суперкласс «...» ошибки super.init()

+0

Так в чем проблема? Сообщение об ошибке ясно. 'super.init' не является назначенным инициализатором - вы сами объявили его инициализатором удобства. Почему вы удивлены? – matt

+0

@matt - Мне любопытно, как лучше всего использовать этот шаблон. Я определяю метод инициализации удобства для выполнения инъекции зависимостей в 'init()' для подкласса UIViewController. Когда я подклассифицирую подкласс, я хочу иметь возможность выполнить одну и ту же инъекцию зависимостей на 'init()', просто измените некоторые функции. Это был простой образец для реализации в ObjC. Я спрашиваю, какой будет лучшая модель Swift. Все ответы, включая ваши, бросают ошибки компилятора в Swift 2.0 и, похоже, не применяются к фреймворкам UIKit (или, по крайней мере, не к UIViewController) – dmorrow

+0

Mine не бросает никакой ошибки компилятора в Swift 2.0/iOS 9. I попробовал! – matt

ответ

10

Вы должны сделать свой Инициализаторы назначенный, не convenience:

class A : UIViewController { 
    init() { 
     super.init(nibName:nil, bundle:nil) 
    } 
    required init?(coder aDecoder: NSCoder) { 
     fatalError("") 
    } 
} 

class B : A { 
    override init() { 
     super.init() 
    } 
    required init?(coder aDecoder: NSCoder) { 
     fatalError("") 
    } 
} 

Это дает структуру наследования, которую вы ищете.

+3

Возможно, вы захотите прочитать мою книгу, в которой объясняются правила инициализаторов классов (хотя вам действительно вряд ли нужно - все, что у вас есть) сделать это, послушать то, что говорит компилятор): http://www.apeth.com/swiftBook/ch04.html#_class_initializers – matt

+0

Компилятор не позволяет мне инициализировать инициализатор инициализатора. Это заставляет меня добавить «удобство» 'с ошибкой _Designated initializer для '...' не может делегировать (с 'self.init'), вы имели в виду, что это инициализатор удобства? _ Если я добавлю' required', это не поможет заставить его быть назначенный init, его просто необходимо было отменить подклассом – dmorrow

+0

Вы не и вставьте то, что я на самом деле написал. То, что я написал, работает. – matt

3

Взгляните на эти изображения, содержащиеся в документации.

По удобству изображения инициализаторах не наследуются. Поэтому, если вы хотите наследовать, вы должны сделать его назначенным инициализатором.

class A : UIViewController { 
    init() { 
     super.init(nibName: nil, bundle: nil) 
    } 
    required init(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 
} 

class B : A { 
    override init() { 
     super.init() 
    } 
    required init(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 
} 

В этой точке вы можете задаться вопросом, что такое разница между назначенным и удобным инициализатором? Ну, Convenience используется для вызова назначенного инициализатора в том же классе, и вы полагаетесь использовать его для создания некоторой настройки.

+0

Это вызывает две ошибки: «Инициализатор не переопределяет назначенный инициализатор из своего суперкласса» в init и «Должен вызывать назначенный инициализатор суперкласса» ... »на super.init() – dmorrow

+0

Я обновил свой ответ. У него нет ошибок. – DerrickHo328

+0

Я вижу, что вы изменили 'self.init (nibName: ...' to 'super.init (nibName: ...' как ответ @ matt ответ ниже. Однако у него был правильный ответ, прежде чем вы обновили свой ответ, поэтому я 'm, отмечая его, как ответ. Я удалил свое голосование, так как ваш ответ теперь корректен. – dmorrow

0

Согласно документу

Правило 2 Удобный инициализатор должен вызвать другой инициализатора из того же класса.

От https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html(Initializer делегации по типам класса)

Вы должны назвать его собственный инициализатор вместо:

class B : A { 
     convenience init() { 
     init() 
     ... 
     }  
    } 

И Init() автоматически унаследовать от него это суперкласс версия

0

Вот правила как передача назначенных инициализаторов и инициализаторов удобства правило 1: Назначенный инициализатор должен вызывать назначенный инициализатор из своего непосредственного суперкласса.

Правило 2: Инициализатор удобства должен вызвать другой инициализатор из того же класса.

Правило 3: Инициализатор удобства должен в конечном итоге вызвать назначенный инициализатор.

Простой способ запомнить это:

Назначенные Инициализаторы всегда должен делегат от. Инициализаторы удобства всегда должны быть делегат через.

Смежные вопросы