Раннее предупреждение - ответь немного долго ...
Используйте объекты, которые моделируют ваш домен. Вам не нужны синглтоны или глобалы, вам нужен регулярный экземпляр обычного класса. Какие объекты вы храните в глобальном массиве? Создайте класс, который представляет эту часть вашей модели.
Если вы используете NSMutableArray в качестве хранилища, оно должно быть внутренним для вашего класса и невидимым для внешних объектов. например, если вы моделируете зоопарк, не делайте
[[[MyGlobals sharedMyGlobals].globalArray] addObject:tomTheZebra];
сделать
[doc addAnimal:tomTheZebra];
Не пытайтесь наблюдать изменяемый массив - вы хотите наблюдать свойство to-many вашего объекта. например. вместо
[[[MyGlobals sharedMyGlobals].globalArray] addObserver:_controller]
хочешь
[doc addObserver:_controller forKeyPath:@"animals" options:0 context:nil];
где doc соответствует kvo для свойства anamals для многих.
Чтобы сделать doc kvo-совместимым, вам необходимо реализовать эти методы (примечание: вам все это не нужно. Некоторые из них необязательны, но лучше для производительности)
- (NSArray *)animals;
- (NSUInteger)countOfAnimals;
- (id)objectInAnimalsAtIndex:(NSUInteger)i;
- (id)AnimalsAtIndexes:(NSIndexSet *)ix;
- (void)insertObject:(id)val inAnimalsAtIndex:(NSUInteger)i;
- (void)insertAnimals:atIndexes:(NSIndexSet *)ix;
- (void)removeObjectFromAnimalsAtIndex:(NSUInteger)i;
- (void)removeAnimalsAtIndexes:(NSIndexSet *)ix;
- (void)replaceObjectInAnimalsAtIndex:(NSUInteger)i withObject:(id)val;
- (void)replaceAnimalsAtIndexes:(NSIndexSet *)ix withAnimals:(NSArray *)vals;
Хорошо, это выглядит довольно страшно, но это не так уж и плохо, как я и сказал, что они вам все не нужны. Смотрите здесь . Эти методы не обязательно должны быть частью интерфейса вашей модели, вы можете просто добавить: -
- (void)addAnimal:(id)val;
- (void)removeAnimal:(id)val;
и запишите их в терминах средств доступа kvc. Ключевым моментом является то, что не массив отправляет уведомления при его изменении, массив - это просто хранилище за кулисами, это класс вашей модели, который отправляет уведомления о добавлении или удалении объектов.
Возможно, вам придется реструктурировать ваше приложение. Возможно, вам придется вообще забыть о NSArrayController.
Aaaaaannnnnyyywaaayyy ... все это ничего не даст вам, если вы сделаете это
[[[MyGlobals sharedMyGlobals].globalArray] addObject:theNewObject];
или это
[doc addAnimal:tomTheZebra];
из фоновой темы. Вы не можете сделать это. NSMutableArray не является потокобезопасным. Если кажется, что это работает, то лучшее, что произойдет, это то, что уведомление kvo / binding доставляется также в фоновом режиме, а это означает, что вы попытаетесь обновить свой графический интерфейс в фоновом режиме, чего вы абсолютно не можете сделать. Боюсь, создание статического массива никоим образом не поможет - вы должны придумать стратегию для этого ... самый простой способ - performSelectorOnMainThread
, но помимо этого - совершенно другой вопрос. Резьба трудная.
А насчет статического массива - просто перестаньте использовать статический, он вам не нужен. Не потому, что у вас есть 2 пера, 2 окна или что-то еще. У вас есть экземпляр, который представляет вашу модель, и вы передаете указатель на него viewControllers, windowControllers, что угодно. Отсутствие одиночных / статических переменных очень помогает при тестировании, что, конечно, вам следует делать.