2015-03-14 4 views
1

Я работаю над приложением с тремя представлениями, которые одновременно отображаются на экране и совместно используют одну и ту же модель данных - объект Swift, который также имеет дочерние объекты. Каждое представление представляет данные по-другому и предоставляет пользователю способы изменения таких данных, таких как переупорядочение элементов, добавление/удаление элементов и т. Д. Кроме того, определенные действия пользователя вызывают асинхронные обновления модели, такие как выбор дополнительной информации для элементов из API. Моя цель - найти архитектуру, которая позволяет мне сообщать контроллеру каждого представления об обновлениях данных без необходимости императивно связываться между контроллерами представлений.Что такое обычная архитектура для распространения обновлений данных для многих ViewControllers?

Каков традиционный подход к этой проблеме?

ответ

0

Общие подходы подписаться на NSNotification с, которые уведомляют наблюдателей, что обновление произошло:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateData:) name:kAppDidUpdateDataNotification object:nil]; 

Затем источник данных может посылать уведомления абонентов:

[[NSNotificationCenter defaultCenter] postNotificationName:kAppDidUpdateDataNotification 
                object:object]; 

Другой подход заключается в общий источник данных и использовать на нем Key Value Observing. KVO позволяет подписываться на обновления на keyPath (например, свойство вашего источника данных). KVO немного волосатый - я рекомендую использовать библиотеку, которая обертывает ее во что-то, что поддерживает блоки, или, может быть, рассматривает фреймворк вроде ReactiveCocoa, который имеет схожие свойства. Обратите внимание, что вы также можете использовать observe changes to collections с KVO, что приятно, если у вас есть, например, NSMutableArray элементов с несколькими диспетчерами представления таблиц, отображающих их, и вы хотите делать такие вещи, как оживить удаление строк в определенных индексах, поскольку объекты удаляются из массива. Поскольку вы упомянули о переупорядочении и добавлении/удалении элементов, это может быть особенно удобно для вас.

+0

благодарит за ответ. ReactiveCocoa - это то, что мы рассмотрели, но когда проект находится в очень изменчивом состоянии, мы немного нерешительны, чтобы пойти олл-ин на нем; не говоря уже о когнитивных издержках перехода на столь драматически различную парадигму программирования. NSNotificationCenter кажется достаточно простым, но более мелкомасштабное наблюдение KVO кажется идеальным для нашего случая использования, как вы упомянули. Знаете ли вы, есть ли быстрые библиотеки, которые обертывают KVO, чтобы сделать его менее волосатым? – bloudermilk

+0

Я не очень хорошо знаком с Swift, поэтому я не уверен, какие библиотеки лучше всего использовать. – MaxGabriel

+0

Основываясь на моих исследованиях, это похоже на традиционный подход – bloudermilk

0

Добавить список делегатов в вашу модель данных и всякий раз, когда происходит событие, прокрутите список и сообщите его делегату. Это расширение шаблона делегирования Objective-C и очень похоже на центр addObserver//.

protocol DataModelDelegate { 
    func dataModel(dataModel: DataModel, didFetchData data: String) // Or any other events 
} 

class DataModel { 
    private delegates = [DataModelDelegates]() 

    func addDelegate(delegate: DataModelDelegate) { delegates.append(delegate) } 
    func removeDelegate(delegate: DataModelDelegate) { // Remove `delegate` from `delegates` } 

    func dataFetched(data: String) { // Or any other events 
     for d in delegates { d.dataModel(self, didFetchData: data) } 
    } 
} 

... 

class ViewController1: UIViewController, DataModelDelegate { 
    private dataModel: DataModel! 

    init(dataModel: DataModel) { 
     ... 
     self.dataModel = dataModel 
     dataModel.addDelegate(self) 
     ... 
    } 

    deinit { 
     // Retain cycle without this! 
     dataModel.removeDelegate(self) 
    } 

    func dataModel(dataModel: DataModel, didFetchData data: String) { 
     // Update UI, etc 
    } 

} 

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

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

Смежные вопросы