Это не контроллер, это контроллер представления. Это либо явное в имени класса (UIViewController, UITableViewController), либо неявное (UITabBarController, поскольку UITabBar - это представление; UINavigationController, поскольку навигация - это парадигма, а UINavigationController имеет очень тонкий представление). 1003 *
Единственный неконтролируемый «Контроллер», о котором я могу думать, это NSFetchedResultsContoller.
Но почему странный дизайн?
Частично это связано с парадигмой пользовательского интерфейса iPhone: пользователи взаимодействуют с экранами одновременно. Если «экран» не виден, то большая часть его памяти может быть восстановлена. Контроллеры UIViewControllers представляют собой экран и управляют взаимодействием экранов с другими экранами.
(Конечно, Apple немного расширила это на iPad для реализации всплывающих окон / разделенных представлений, но эти два по-прежнему фактически являются «экранами» вместо общих представлений. Контроллеры представления в некоторой степени аналогичны окнам в настольной ОС, за исключением того, что большинство они не видны большую часть времени.)
Частично это связано с CoreAnimation: UIView обрабатывает рисование / макет и поддерживается CALayers. CALayers эффективно представляют текстурированные полики на GPU; «содержимое слоя» (то есть текстура) не может быть произвольно выгружено в свободную память. (Я не совсем уверен, почему, но это означает, что вы можете один раз установить для содержимого CGImage и оставить его в покое.) Поскольку многие свойства представления поддерживаются свойствами слоя (frame, bounds, center, contentStretch, .. ., немного глупо позволять представлению существовать без слоя. Конечный результат заключается в том, что представления имеют большой вес и иногда должны исчезать при нехватке памяти, поэтому контроллеру представления необходимо отслеживать вещи, которые должны сохраняться при выгрузке / перезагрузке представления (позиция прокрутки, выбранный в данный момент элемент, ...). Да, он может попросить представление сериализовать себя, но сериализация icky и большинство вещей не нуждается в сериализации.
Частично это связано с ленью: вам нужно реализовать контроллер представления, чтобы справиться с тем, как он взаимодействует с другими контроллерами представления. С другой стороны, представления выполняют автоматическое изменение размера & mdash; если вы счастливы установить макет в кончике или в -viewDidLoad, вам часто не нужно писать собственный вид. Лень требует, чтобы вы этого не делали, поэтому в контроллере представления часто выполняется макет.
Лично я реализую «умное» представление, когда оно кажется более логичным. Возьмем, к примеру, приложение «Погода»: когда загружается представление, вы должны отображать погоду в течение нескольких дней в каждой ячейке (которая может быть или не быть ячейкой табличного представления; это не имеет значения). Когда вы получаете обновление, вы должны обновить все ячейки. Вы могли бы реализовать - [WeatherViewController updateCell:], но, кажется, имеет больше смысла просто иметь - [WeatherCell setWeather:] и передать его вашей модели. В контроллере вида намного меньше беспорядка.
Я также виню лень и ремонтопригодность: иногда просто проще иметь все в одном файле, а иногда полудублированный код с небольшими специализациями проще, чем написание универсального представления, поддерживающего все его варианты использования. Это намного лучше, чем Enterprise Java, где принято иметь функцию, которая вызывает функцию, которая вызывает функцию, которая вызывает (единственную функцию, которая создается) -с фабрикой-с-некоторым-классом, который вам нужен для отслеживания) -призывает-функцию-то-вызывает-функцию, чтобы выяснить, что корпоративное программное обеспечение использует алгоритм хеширования пароля, который может быть выражен в 1 строке Python. (Я немного преувеличиваю.)
(Так что же произойдет, если вы решите, что общий макет погодной ячейки подходит, например, для отображения фазы / видимости луны? Переместите универсальный материал в суперкласс и сделайте AstronomerCell или что-то еще.)
Кроме того, если ваши представления не могут работать с фиктивным контроллером, вы делаете это неправильно.Представления не должны знать об их контроллере представления;контроллер представления должен зарегистрировать себя как цель действия (addAction: target: forControlEvents :, я думаю) или соответствующий делегат.Никто из них не ожидает, что целью будет контроллер представления.