Короче говоря, вам нужно переопределять квалификатор всякий раз, когда вы реализуете метод или свойство, которые реализовал базовый класс. Например, когда вы реализуете viewDidLoad
в подклассе UIViewController
, вам нужно указать override
, потому что вы переопределяете метод viewDidLoad
, уже реализованный в UIViewController
.
Для получения дополнительной информации о переопределении см. Язык программирования Swift: Наследование: Переопределение .
Так что в случае сцен с табличными представлениями вы увидите один из двух базовые c шаблоны:
Если вы подклассифицировали UIViewController
и добавили к этому свой собственный UITableView
, у вас будет реализация, подобная:
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
...
}
}
// MARK: - UITableViewDataSource
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
...
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
}
}
В этом сценарии вы бы:
- в Интерфейсном Разработчике (IB) подключили бы выход к представлению таблицы;
- укажите контроллер представления как « источник данных »(и, вероятно, также« делегат ») для табличного представления (вы можете сделать это либо в IB напрямую, либо программно в вашем методе
viewDidLoad
); но - обратите внимание, что в двух
UITableViewDataSource
методах нет ключевого слова override
, поскольку UIViewController
не реализовал эти методы.
Обратите внимание, что я определил соответствие UITableViewDataSource
в расширении. (См. Язык программирования Swift: Протоколы: добавление соответствия протокола расширению .) Вам не нужно этого делать, но он сохраняет код в вашем контроллере представления хорошо организованным, если вы объявляете соответствие протокола в расширение. Это не только понятно и недвусмысленно, но если вы делаете свертывание кода в XCode (где вы можете свернуть разделы вашего кода, чтобы вы могли сосредоточиться на других частях вашего кода). Это хорошая привычка.
В качестве альтернативы, если вы подклассифицируете UITableViewController
, тогда вам понадобится объявление override
для этих двух методов источника данных, потому что вы переопределяем те два метода, которые уже были объявлены в базовом классе, UITableViewController
:
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
...
}
}
// MARK: - UITableViewDataSource
extension ViewController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
...
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
}
}
Очевидно, что при использовании UITableViewController
:
- вы не делаете необходимо объявить выход
tableView
или указать источник данных или делегат в IB; - вы явно не указываете соответствие
UITableViewDataSource
(поскольку базовый класс UITableViewController
уже соответствует этому протоколу) ; но - вы должны включить ключевое слово
override
в свою реализацию этих UITableViewDataSource
методов.
С точки зрения того, когда вы используете один подход а не другой, это вопрос того, что присутствует в вашем пользовательском интерфейсе. Если вы согласны с табличным представлением как root представлением сцены вашего контроллера представления, то UITableViewController
, возможно, немного проще. Но если сцена вашего контроллера представления может включать другие элементы управления, где табличное представление может не занимать всю сцену, тогда вы захотите принять шаблон UIViewController
, где вы можете добавить столько выходов и элементов управления в вашей сцене раскадровки, которые вам могут понадобиться .