Подтвердить что ты не робот

Какой инициализатор переопределить для подкласса UITableViewController

У меня есть подкласс UITableViewController, который создается в зависимости от того, где он используется, в NIB или через код. В обоих случаях я хочу выполнить настройку в методе инициализации. Означает ли это, что мне нужно реализовать как initWithNibName:bundle:, так и initWithCoder:, и будет ли каждый метод вызывать его соответствующий супер инициализатор?

Пока мне это не нужно прямо сейчас, что делать, если я также хочу создать экземпляр контроллера представления с помощью initWithStyle:? Нужно ли мне тогда 3 разных метода init, которые повторяют одно и то же поведение?

Похоже, что это нарушает все назначенное соглашение инициализатора, так как по существу есть 3 отдельных инициализатора, которые в конечном итоге не вызовут обычный метод init. Или есть способ создать общий назначенный инициализатор, поддерживая три разных маршрута-экземпляра?

4b9b3361

Ответ 1

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

  • initWithStyle: объявлен локально
  • initWithNibName:bundle: унаследовано от UIViewController
  • initWithCoder: от принятия протокола NSCoding

Вам нужно переопределить 1 или более из них в вашем подклассе в зависимости от того, как создается ваш подкласс. В моем случае мне пришлось реализовать # 2 и # 3, поскольку класс может быть загружен из NIB или создан с помощью кода со ссылкой на NIB. (Я полагаю, что редко можно использовать как initWithStyle:, так и initWithNibName:bundle: для одного класса.)

Я нашел Apple Полезные советы по кодированию Cocoa.

Ответ 2

Внутри

  • UITableViewController -initWithStyle: вызывает супер -init, затем устанавливает _tableViewStyle ivar.
  • UIViewController -init просто вызывает -initWithNibName:bundle: с аргументами по умолчанию.
  • UITableViewController не переопределяет -initWithNibName:bundle:.

Поэтому, если вы переопределяете -initWithNibName:bundle:, тогда -initWithStyle: тоже примет это изменение. Конечно, чтобы играть безопасно (так как вы не должны полагаться на детали реализации), переопределите их оба.

(И не нужно переопределять -initWithCoder:, если вы не удалите/архивируете экземпляры.)

Ответ 3

Чтобы уточнить, initWithStyle:, будучи UITableViewController, только опубликованный инициализатор в документах, является его единственным явным назначенным инициализатором.

initWithNibName:bundle: наследуется от UIViewController и является назначенным инициализатором для этого класса. Таким образом, в соответствии с рекомендациями Cocoa UITableViewController должен переопределить этот метод (путем его реализации). Однако это не делает его назначенным инициализатором UITableViewController.

initWithCoder:, как вы указываете, является неявным назначенным инициализатором из NSCoding.

Ответ 4

Реализовать:

- (void) viewDidLoad

и выполните инициализацию вашего компонента.

Преимущество имеет только выполнение инициализации, когда запрос действительно запрашивается.

Или просто создайте отдельный метод установки, который вызывается всеми инициализаторами.

Ответ 5

Добавление к сообщениям выше этой ссылки -initWithCoder:

Если вы добавили контроллер представления к своему родителю через построитель интерфейса (например: если контроллер представления подключен к контроллеру панели вкладок в построителе интерфейса), вам необходимо переопределить -initWithCoder.

(- initWithNibName будет вызываться только при программном программировании контроллера вида.)