где хранить данные основного представления таблицы? (appDelegate или rootViewController)

Любые советы о том, где хранить данные основного списка для приложения iPhone, как показано ниже?

  • NavigationController на основе
  • Уровень 1 (главный экран) — это список элементов. Следовательно, он использует табличное представление (таблица элементов)
  • Уровень 2_РЕДАКТИРОВАТЬ: это представление, к которому можно перейти с главного экрана, нажав ИЗМЕНИТЬ. Здесь вы можете добавить текст, который будет добавлен в основной список просмотра.
  • Уровень 2_DETAIL: представление, к которому можно перейти с главного экрана, щелкнув ячейку.

Теперь предположим, что реализация такова (приблизительный обзор): * MainView - appDelegate (содержит UIWindow и UINavigationController) * RootViewController - табличное представление списка основных элементов (? Здесь переменные?) * EditViewController - ввод текста для добавления в основной список * DetailViewController - показывает деталь записи

Вопрос. Где хранить NSArray основной список элементов? Должен ли он быть в RootViewController, где существует табличное представление, которое отображает его? Или он должен быть выше в ApplicationDelegate? Я отмечаю, что когда вы переходите от RootViewController к EditViewController, то в этом режиме редактирования вам придется ДОБАВЛЯТЬ элементы в массив, поэтому коду в EditViewController будет проще получить доступ к основному массиву из AppDelegate (в отличие от RootViewController)?

(Примечание: пока еще не создано приложение с определенным объектом модели, в отношении MVC, поэтому не уверен, что это должно появиться на картинке.)


person Greg    schedule 22.02.2011    source источник


Ответы (2)


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

Пример проекта Apple CoreDataBooks демонстрирует аналогичную архитектуру. Вы можете взглянуть.

Наличие массива в делегате приложения часто не лучшая идея. Хотя это может дать вам некоторое удобство, теперь ваши классы полностью зависят от вашего делегата приложения без необходимости.


В табличном представлении отображаются ваши данные. Это соответствует View в шаблоне проектирования MVC. Я предполагаю, что RootViewController — это контроллер представления табличного представления, который действует как Контроллер в шаблоне. Ваши данные, расположение которых еще не определено, соответствуют Модели. Роль RootViewController заключается в соединении Модели и Представления.

Идеал или причина шаблона MVC состоит в том, чтобы изолировать модель и представление, чтобы модель могла работать с другими представлениями с соответствующими контроллерами, а представление также могло работать с другими моделями с соответствующими контроллерами. Например, ваш RootViewController предоставит табличное представление с данными. Он будет указывать данные на языке табличного представления, например. количество разделов и строк, содержимое ячеек и т. д. Если вы хотите представить данные по-другому, например, в виде графика, ваш контроллер получит доступ к тем же данным (модели) и предоставит представление графика с другим представлением одних и тех же данных. Модель не должна меняться, равно как и представления. Вы пишете только контроллер для каждой комбинации модели и представления.

Поэтому в идеале у вас будет другой класс для модели. В этом классе вы будете хранить массив и предоставлять общий интерфейс для взаимодействия контроллеров с данными.

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

Вот почему имеет смысл, что ваш контроллер табличного представления часто действует как источник данных табличного представления.

Однако хранение данных в делегате приложения — это совершенно другая идея. Теперь делегат приложения становится вашей моделью, но это не имеет смысла, поскольку делегат приложения используется только для конкретного приложения. Зачем вам отдельный объект модели, который полностью зависит от одного приложения? Кроме того, если ваше табличное представление напрямую взаимодействует с делегатом приложения, это означает, что теперь ваше представление не может работать и для других приложений, потому что теперь оно зависит от делегата приложения конкретного приложения.

Часто причина, по которой люди испытывают искушение иметь данные в делегате приложения, заключается в том, что делегат приложения легко доступен любым объектам в приложении с помощью [UIApplication sharedApplication].delegate. Отношения M-V-C не всегда очень просты. Например, ваш EditViewController также должен иметь доступ к той же модели. Для этого вам нужно написать некоторый код, чтобы сделать модель доступной как для табличного представления, так и для редактирования. Если у вас есть данные в делегате приложения, вам не нужно ничего делать, потому что вы можете волшебным образом получить доступ к массиву, обратившись к делегату приложения.

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

Итак, как вы должны связать свое представление редактирования с данными, объединенными в контроллер табличного представления? Способов может быть несколько. Раньше я предлагал, чтобы контроллер представления редактирования имел слабую ссылку на контроллер табличного представления (delegate) и отправлял определенное сообщение, например - (void)editViewController:(EditViewController *editViewController) didFinishEditing:(id) someData. Таким образом, вы можете использовать этот контроллер представления редактирования с некоторыми другими контроллерами представления, если они используют один и тот же протокол. Но другие могут реализовывать для него другие интерфейсы.

person MHC    schedule 22.02.2011
comment
@MHC - да, видите ли, что вы говорите, но есть ли какие-либо недостатки в сохранении ваших данных как части источника данных контроллера? Например, что, если вы используете разные контроллеры/представления (например, страницы справки, страницы конфигурации), которым не нужны данные. Есть ли проблемы с сохранением таких данных в течение срока службы приложения? Также будет ли мне, как новичку, рекомендован пример CoreData? (возможно, я просто еще больше запутаюсь на данный момент) - person Greg; 22.02.2011
comment
Не уверен, что вы спрашиваете в комментарии (за исключением последней части), что может показать, что мой ответ не ясен, поэтому позвольте мне уточнить свой ответ. - person MHC; 22.02.2011
comment
спасибо - я думаю, мне было интересно, есть ли проблема с конкретным контроллером, содержащим ссылку на объект модели, который вам нужен на протяжении всей жизни приложения? Отбрасываются ли объекты контроллера (состояние /lose there), когда они не используются активно, например, для отображения представления? Поэтому мне интересно, будет ли AppDelegate лучше хранить ссылку на объект вашей модели с точки зрения обеспечения того, чтобы он оставался ...? - person Greg; 22.02.2011
comment
контроллер представления обычно не сохраняется/освобождается поведением Cocoa по умолчанию. Если вам нужно сохранить контроллер представления (обычно вы это делаете), вы должны сохранить его (корневой контроллер представления обычно сохраняется делегатом приложения, а другие контроллеры представления - корневым контроллером представления или другими суперподобными контроллерами представления. Это может быть быть сохранены логикой загрузки пера через выходы). И если вы не отпустите его, контроллер представления никогда не будет освобожден. - person MHC; 22.02.2011
comment
фантастический MHC - я бы дважды проголосовал за вас, если бы мог - могу я спросить в вашем последнем абзаце о том, как контроллер представления редактирования отправляет сообщение, как это будет работать - например, как editViewController получит дескриптор основного контроллера TableView? Я еще не дошел до реализации Table View, щелкнув строку для запуска на отдельный контроллер, но я предполагаю, что в этот момент есть способ передать ссылку? - person Greg; 22.02.2011
comment
Да - если EditViewController создается в контроллере табличного представления (что обычно), вы можете просто установить его как newEditViewController.delegate = self;. Убедитесь, что свойство делегата EditViewController реализовано как назначение и не сохраняет контроллер табличного представления. - person MHC; 22.02.2011
comment
О, я не вижу поле делегата в UIViewController? - person Greg; 23.02.2011
comment
Конечно, вы добавите переменную экземпляра типа id в EditViewController и создадите свойство с именем делегата (имя не обязательно должно быть делегатом, но оно показывает шаблон проектирования). Если вы хотите определить протокол для этого делегирования, вы можете объявить протокол, скажем, EdivViewControllerProtocol, и использовать тип if id ‹ EditViewControllerDelegate ›. - person MHC; 23.02.2011

Вам нужно сохранить в appDelegate, так как вы можете получить данные в любом контроллере просмотра. Но если вы используете rootviewController, тогда вы можете отправлять данные только в следующий ViewController, а не во второй или третий ViewController напрямую. Надеюсь, это поможет вам.

Удачи

person Sabby    schedule 22.02.2011
comment
спасибо - не возражаете, если я спрошу, где вы видите, что здесь вступает в игру класс Model? - person Greg; 22.02.2011