Ну, на мой взгляд, лучший подход - это использовать шаблон архитектуры MVVM (Model-View-ViewModel).
1) Для каждого из ваших UIViewController создайте отдельный класс (производный от NSObject, если хотите), который вы считаете «моделью представления», принадлежащей этому UIViewController. Вашим контроллерам представления не разрешен доступ к классам модели ... теперь это работа ваших классов "модели представления".
2) Создайте синглтон с именем, скажем, DependencyManager. Ваши модели представлений обращаются к нему, чтобы получить ваши модели (или, по крайней мере, модели верхнего уровня, если они иерархические) и все, что им может понадобиться, например, сетевые сервисы и т. Д. DependencyManager действует как способ, которым ваши модульные тесты могут внедрить замену ». "Моделирование" версий ваших моделей, сетевых служб и т. д. ... когда пришло время протестировать каждую модель представления.
3) Создайте класс (ы) вашей модели, которые содержат данные. Ваши контроллеры представления собрали различные данные в элементах управления пользовательского интерфейса и передали эти необработанные данные вашим viewModels. Модели представления могут изменять эти данные (или нет) и прикреплять их к соответствующим моделям, которые они получают из DependencyManager.
4) ViewController также может запрашивать данные у своего viewModel. Таким образом, ваш последний ViewController будет получать все необходимые данные из своей viewModel.
Помните: ViewControllers не должны напрямую манипулировать вашими модельными классами.
Кроме того, ваши ViewModels никогда не должны ссылаться на какие-либо объекты пользовательского интерфейса или даже иметь ссылку на свой ViewController.
Примечание: я рекомендую, чтобы каждая ViewModel соответствовала протоколу, который происходит от пустого протокола с именем что-то вроде «MockableViewModelProtocol». Вы можете добавить одно свойство к вашему DependencyManager типа MockableViewModelProtocol, которое каждый из ваших ViewControllers может проверить перед созданием своей ViewModel, в случае, если модульный тест назначил фиктивную ViewModel для замены ViewController. Еще одним преимуществом такого протокола является быстрое и четкое понимание взаимосвязи между ViewModel и его ViewController. Часто у вас будут не только свойства и методы, но и свойства обратного вызова (свойства замыкания).
Итак, поехали. Это, на мой взгляд, лучший способ не только разработать способ управления и доступа к данным среди множества viewControllers, но также протестировать все ваши классы и их использование этих данных.
И в отличие от всех текущих утверждений, что раскадровки блокируют внедрение зависимостей и, таким образом, предотвращают тестирование ваших контроллеров ViewController, это всего лишь пустяк. Используя DependencyManager, так что тесты вашего контроллера представления внедряют там макеты, тесты получают то же преимущество, как если бы они вводили макет непосредственно в ViewController, и, тем не менее, ViewController все еще создается Storyboard. С таким подходом я успешно отправил большое приложение.