Автоматическая загрузка XIB для UITableViewController - PullRequest
5 голосов
/ 08 апреля 2010

Наткнулся на что-то интересное, хотите узнать, правильно ли я поступаю или это правильное поведение.

У меня есть пользовательский UITableViewController. Я предположил (первая ошибка), что если вы инициализируете так:

[[CustomTableController alloc] init];

он будет автоматически загружаться из XIB с тем же именем, CustomTableController.xib, если он находится в том же каталоге и тому подобное.

ОДНАКО

Это не работает; не загружает XIB. НО, если я изменю родительский класс моего контроллера с «UITableViewController» на «UIViewController», ВСЕ РАБОТАЕТ КАК МОЖНО!

Призвание:

[[CustomTableController alloc] init];

загружает контроллер и просмотр с моего xib.

Я что-то не так делаю? Это ошибка? Ожидаемое поведение?

1 Ответ

26 голосов
/ 10 апреля 2010

Большинство классов в Cocoa Touch перечисляют «назначенный инициализатор», который вы должны вызывать из ваших init методов, когда вы создаете их подклассы. Когда вы создаете свой собственный класс, рекомендуется проверить документацию, чтобы найти назначенный инициализатор для вашего суперкласса. Когда вы инициализируете класс, используя какой-то другой инициализатор из более общего суперкласса (который вы делаете, вызывая - [NSObject init] в этом случае), вы лишаете свой прямой суперкласс его возможности правильно инициализировать его состояние. Иногда это можно сойти с рук. Часто вы не можете.

Документация UIViewController гласит, что его назначенный инициализатор - initWithNibName:bundle:. Если вы вызываете этот метод с nil nibName, он будет искать nib, соответствующее вашему имени класса. Поведение -init недокументировано для UIViewController. В зависимости от поведения, которое вы видите, кажется, что он может вызывать [self initWithNibName:nil bundle:nil], но было бы безопаснее вызвать initWithNibName:bundle: напрямую, а не полагаться на это недокументированное поведение.

UITableViewController определяет только один инициализатор, -initWithStyle: (хотя он не определяет этот метод в качестве назначенного инициализатора). Этот метод инициализирует ваш UITableViewController без использования пера, что обычно хорошо. Поскольку вы не добавляете подпредставления в UITableView, обычно при настройке UITableViewController с помощью пера не так много можно получить.

Если вы в любом случае решите, что хотите сконфигурировать свой UITableViewController через перо, в документации говорится, что мы можем безопасно обойти -initWithStyle: и вызвать метод initWithNibName:bundle: UIViewController. Вот что говорит нам документация о том, как наш UITableView и его контроллер будут инициализироваться в каждом случае:

  • Если файл пера указан с помощью метода initWithNibName:bundle: (который объявлен суперклассом UIViewController), UITableViewController загружает табличное представление, заархивированное в файле пера. В противном случае он создает ненастроенный объект UITableView с правильными размерами и маской авторазмера. Вы можете получить доступ к этому представлению через свойство tableView.

  • Если загружен файл пера, содержащий представление таблицы, источником данных и делегатом становятся те объекты, которые определены в файле пера (если есть). Если файл пера не указан или если в файле пера не указан источник данных или делегат, UITableViewController устанавливает для источника данных и делегата табличного представления значение self.

Таким образом, в документации для большинства классов Cocoa Touch указывается либо один назначенный инициализатор, либо несколько инициализаторов, которые можно безопасно вызывать из своих подклассов. Всегда обращайтесь к документации вашего суперкласса, чтобы выяснить, какой инициализатор должен вызывать ваш подкласс.

...