Обязанности контроллера в архитектуре MVC

У меня есть текущая база кода, которую я хочу реорганизовать. Контроллер (или viewcontroller для людей, знакомых с iOS) составляет около 2000 строк и делает много вещей.

 Контролер отвечает за: 
 1) Общение между представлением и моделью

 1.1) Обработка обратных вызовов / действий из представления
 1.2) Обработка жестов.
 1.3) Передача данных из модели для просмотра. 

 2) Выполнение веб-запроса, если модель пуста. 

 2.1) подготовка URL-адреса и отправка запроса обработчику соединения. 
 2.2) Логика анализа

 3) Пользовательский интерфейс 

 3.1) Незначительные изменения пользовательского интерфейса. 

 4) Бизнес-логика. 

 4.1) Немного кода имеет дело с бизнес-логикой расчета некоторых отчетов. 

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

Кроме того, более конкретно я хочу знать, кто несет ответственность за создание модели веб-запроса или контроллера?

Есть несколько понятий, которые были полезны для меня в письменной форме:

  1. В дополнение к конкретным объектам модели (например, если вы запрашиваете информацию о погоде от службы, у вас может быть класс Weather который представляет конкретный метеорологический отчет, например, city , temperature и narrative свойства), я также буду использовать данные объект контроллера, который координирует запрос объектов из кеша, постоянного хранилища или из Интернета, в зависимости от ситуации (часто в этом порядке). Вы хотите быть осторожным, полагаясь исключительно на упрощенные запросы веб-службы, поскольку кеши и тому подобное могут быть весьма важными при разработке адаптивного пользовательского интерфейса.

    Ключевым моментом для меня является то, что я редко хочу, чтобы ни взгляды, ни контроллеры представлений не возились с этим уровнем детализации (хотя, признаюсь, в тривиальных ситуациях я делал запросы непосредственно с контроллера). В идеале контроллер представления инициирует асинхронный запрос моего контроллера данных, передавая ему блок завершения с параметрами (a) возвращаемого объекта модели; и (b) NSError .

    Я приведу пример того, как это будет выглядеть ниже.

  2. Как вы могли бы сделать вывод сверху, я часто также абстрактно рассказываю о деталях инициирования веб-запросов и разбора ответов на свои собственные объекты (потому что контроллер данных может быть достаточно сложным, управлять кэшами, постоянным хранилищем и т. Д.), , Обычно я использую подкласс NSOperation для задач запроса / разбора (который поддается асинхронным запросам с блоками завершения, возможность отменить ожидающие запросы, если пользовательский интерфейс переходит на что-то еще и т. Д.). Таким образом, мой контроллер данных будет, если он заключит, что кэшированное и / или постоянное хранилище не может удовлетворить запрос, инициирует асинхронную операцию запроса / разбора.

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

    • 1.2) Обработка жестов. Если жест немного усложняется (например, только горизонтальный, проведите по краю и т. Д.), Я фактически подклассирую обработчик жестов, значительно упростив собственное взаимодействие с контроллером жестов.

    • 3) Настройка пользовательского интерфейса. Если пользовательский интерфейс требует большой настройки, я часто подклассифицирую соответствующий вид. В частности, с помощью UITableViewCell и UICollectionViewCell это может значительно упростить код контроллера вида. И любые взгляды, требующие какой-либо материальной настройки, часто могут быть сделаны более изящно в подклассе самого представления.


Пример абстракции контроллера данных

Итак, у меня может быть блок завершения, определенный так:

 typedef void(^WeatherRequestCompletion)(WeatherReport *weatherReport, NSError *error); 

И тогда у меня может быть метод в моем контроллере данных с таким интерфейсом:

 - (WeatherRequest *)requestWeatherWithIdentifier:(CityIdentifier)cityIdentifier completion:(WeatherRequestCompletion)completion; 

И мой контроллер просмотра будет использовать его так:

 typeof(self) __weak weakSelf = self; self.weatherRequest = [[WeatherModel sharedController] requestWeatherWithIdentifier:self.cityIdentifier completion:^(WeatherReport *weatherReport, NSError *error) { if (error) { // handle error } if (weatherReport) { weakSelf.cityLabel.text = weatherReport.city; weakSelf.tempLabel.text = [weatherReport.temperature stringValue]; weakSelf.narrativeLabel.text = weatherReport.narrative; } }]; 

Контроллер представления не должен беспокоиться о том, как форматируется запрос и как анализируется ответ (это задание NSOperation моего сетевого запроса). Кроме того, диспетчер представлений не должен быть слишком вовлечен в логику кэширования и / или постоянного хранения (это задача моего контроллера данных). Контроллер обзора должен, таким образом, быть перегнанным на что-то очень логичное и легко следовать.

Заметьте, вы заметите, что мой контроллер данных возвращает объект запроса (который для меня часто является просто typedef для NSOperation ). Я хочу, чтобы мой контроллер просмотра поддерживал weak ссылку на него, поэтому я могу легко отменить запрос, если и когда это необходимо, например, в dealloc контроллера вида):

 - (void)dealloc { [_weatherRequest cancel]; } 

В большинстве случаев это типичное поведение ViewController. У Apple действительно есть хороший документ, описывающий архитектуру MVC подробно: http://developer.apple.com/library/ios/documentation/general/conceptual/devpedia-cocoacore/MVC.html

«Когда объект модели изменяется (например, новые данные принимаются по сетевому соединению), он уведомляет объект контроллера, который обновляет соответствующие объекты вида».

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

  • Как следовать MVC, если у вас много статических данных?
  • Реальный сценарий для реализации MVC vs MVVM vs VIPER для проектов на базе iOS
  • Вручную выполните запуск ViewController и нажмите вверх. Хорошая практика?
  • понимание uiview и uiviewcontroller
  • В программировании IOS есть «Контроллер просмотра» на самом деле контроллер?
  • Кнопка «Назад» отсутствует в моей навигации controntroller
  • Связь iOS между Model и ViewController
  • Что такое «нажатие» контроллера вида?
  • какой метод в UIViewController должен выполнять задачу «заполнения данных» для просмотра?
  • MVC: Является ли «хорошей практикой» переход модели с ViewController на другой?
  • Архитектура iOS MVC, управляемая JSON
  • Interesting Posts

    Предложения по разработке модульного проекта iOS?

    Ошибка UINavigationController в интерактивной ошибкеPopGestureRecognizer на iPhone 6 Plus в альбомной ориентации

    Местное уведомление iOS при прибытии в место

    Может ли Firebase быть надежно использована для обнаружения достижимости, а не для API доступности iOS

    Приложение одобрено, но не показано в App Store iOS

    Какое устройство следует использовать для тестирования приложения iphone

    в чем разница между представлением вида и контейнера в дизайне iOS?

    Как установить идентификатор ячейки TableView в UIViewController?

    Как определить массив CGPoints в определении структуры?

    Как получить nonce из SDK Braintree iOs

    Нужно ли мне звонить CGContextSaveGState и CGContextRestoreGState?

    Метод выбора вызова из другого класса – NSNotificationCenter

    Ошибка Xcode при добавлении нового языка для локализации / перевода

    Может ли ASIWebPageRequest загружать многоуровневые веб-страницы с источниками internel?

    Setters и Getters в среде ARC

    Давайте будем гением компьютера.