Понимание Model-View-Controller

У меня есть приложение, в котором я хочу иметь один "фоновый" вид (вид контроллера), а кроме того, несколько UIView, которые рисуют себя как круги. Я просто не понимаю, как реализовать все это, все еще придерживаясь MVC...

Модель и представление должны быть разными. Означает ли это, что мне обычно нужен один набор файлов заголовка и реализации для представления и другой (отдельный) набор для модели - даже если мой объект является всего лишь классом Circle? Или у меня будет один набор Circle.h и Circle.m, а затем внутри файла заголовка будут два блока интерфейса, один для модели и один для представления, и два блока реализации (опять же один для модели и один для вид)?

Я видел, что некоторые люди рекомендуют использовать контроллер вида для обработки всех представлений в loadView и избегать создания отдельных настраиваемых объектов просмотра; означает ли это, что я не должен создавать отдельный набор файлов .h и .m для представления? Последний кажется намного более организованным с точки зрения дизайна для меня.

Кроме того, если бы у меня было несколько объектов вида и несколько объектов модели, обработанных контроллером представления, я бы сохранил их в двух массивах контроллера - один для моделей, а другой для представлений. Правильно? Мой вопрос: когда я использую наблюдение за ключевыми значениями для каждой модели, как бы я, для каждого объекта модели, изменить правильный соответствующий объект представления (если предположить, что индексы не одинаковы для обоих объектов в обоих массивах)?

Я думал об использовании указателя на объект модели внутри представления и KVOing из представления в модель, но затем он не проходит через контроллер и, таким образом, полностью перекрывает MVC, правильно?

Спасибо заранее.

Ответы

Ответ 1

MVC - большая, широкая идея. Это скорее руководящая философия, чем конкретное правило, и она не всегда реализуется одинаково. Прочитайте обсуждение Apple MVC, чтобы оценить разницу между традиционными MVC и MVC в Cocoa.

Трудно сказать, как применить MVC к вашему приложению, потому что вы не сказали нам, что должно делать приложение, а также это не похоже на реалистичное приложение. Поэтому я сделаю все возможное и сделаю некоторые предположения на этом пути. Приложение, которое просто рисует кучу кругов в фиксированных местоположениях на фоне, не очень интересно - это могут быть почти все виды, практически не требующие какого-либо контроллера. Так что скажем, что круги все движутся в разных направлениях, рисуются разными цветами и изменяются со временем. Теперь у вас появляется потребность в модели, чтобы вы могли отслеживать данные, представленные этими кругами, и контроллер для перевода модели в термины, которые могут быть представлены представлениями.

Поскольку вы задали вопрос об рисовании кругов, давайте начнем с представления. Кажется хорошей идеей иметь пользовательский вид, который знает, как рисовать круг с учетом необходимых параметров: области, цвета и позиции. Вероятно, вы должны сделать эти свойства и переопределить -drawRect: чтобы он рисовал круг данной области в заданном цвете.

Мы не знаем, что представляют собой эти круги, но это не очень весело, если они не представляют что-то, поэтому давайте предположим, что работа с приложениями помогает нам сравнивать корпорации. У нас есть данные о доходах, рыночной капитализации, количестве сотрудников, кредитном рейтинге, имени, тикере и т.д. Вы можете создать пользовательский объект для хранения всех данных для каждой корпорации, или вы можете поместить все это в словарь. Наша модель представляет собой набор этих пользовательских объектов или словарей.

Обратите внимание, что представления кругов ничего не знают о корпорациях, и модель ничего не знает о кругах. Это хорошая вещь. Это также, где входит контроллер. Контроллер - это место, где вы помещаете код, который визуально визуально отображает модель, используя представления. Он также интерпретирует события из представлений, обновляя модель по мере необходимости. Итак, наш диспетчер знает как сведения о корпорациях, так и свойства вида окружности. Он создает круговой обзор для каждой корпорации в модели. Я хочу, чтобы область круга соответствовала капитализации рынка корпорации, вертикальной позиции для представления дохода и горизонтальной позиции для указания количества сотрудников. Мы назначим цвет, основанный на кредитном рейтинге корпорации. Контроллер должен, конечно, следить за всеми видами кругов и каким-то образом отображать между видами кругов и корпорациями.

Теперь у тебя что-то есть. Это все еще довольно простое приложение, но у вас есть полезная диаграмма, сравнивающая корпорации в нескольких измерениях. Пусть улучшит его.

Во-первых, трудно понять, какой круг представляет какую корпорацию. Было бы неплохо, если бы в виде круга можно было отобразить некоторый текст. Давайте добавим свойства названия и субтитров и изменим -drawRect: чтобы нарисовать эти строки выше и ниже круга соответственно. Мы также сменим контроллер так, чтобы щелчок или щелчок по кругу задавали заголовок и субтитры этого круга для имени корпорации и символа тикера или очищали их, если они были предварительно установлены.

Во-вторых, приятно сравнивать корпорации в момент времени, но более интересно, если мы сможем показать изменения с течением времени. Позвольте изменить модель, чтобы включить исторические данные для доходов, рыночной капитализации, сотрудников и рейтинга. Мы можем обновить контроллер, чтобы он мог использовать исторические данные для анимации кругов.

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

Я уверен, что гипотетическое приложение в этом очень длинном объяснении по примеру имеет примерно нулевое сходство с вашим собственным приложением, но, возможно, это поможет объяснить, почему MVC полезен и информирует структуру вашего собственного приложения, Удачи.

Ответ 2

Я получил хорошее объяснение от CS193P РАЗРАБОТКА ПРИМЕНЕНИЯ IPHONE (зима 2013).

Model-View-контроллер:

Разделите все объекты на три лагеря:

enter image description here

Модель: Что ваше приложение (карта, колода, логика карты)
Контроллер: Как ваша модель представлена ​​пользователю (UI Logic). Контроллер знает все о пользовательском интерфейсе.
Вид: ваш контроллер миньонов.

Как общаются эти лагеря:

enter image description here

Не пересекайте желтую линию.
Вы можете пересечь пунктирную белую линию.
некоторые специальные правила существуют для пересечения сплошной белой линии.

enter image description here

Контроллер → Просмотр (через Выход)
View → Controller (через Источник данных (count, dataAt), делегат (должен, должен был), Целевое действие) < ш > Модель → Contoller (через Уведомление и Наблюдение за ключевыми значениями)