Как настроить KVO для Коллекции (NSArray или NSSet) NSManagedObjects - PullRequest
6 голосов
/ 21 марта 2012

У меня есть приложение для iPad с UITableViewController, которое реализует NSFetchedResultsControllerDelegate. (В основном используется CoreDataTableViewController код из классов Stanford iOS.)

У меня есть вторичный объект модели (self.locations), который является массивом Location объектов, который является подклассом NSManagedObjects. Этот массив управляет содержимым UISegmentedControl, который фильтрует мой основной fetchedResultsContoller.

Можно изменить содержимое self.locations с помощью всплывающего окна. Я хочу настроить наблюдения, чтобы мой основной UITableViewController мог наблюдать за изменениями в объектах, хранящихся в self.locations, и при необходимости перезагрузить UISegmentedControl.

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

Мне кажется, я понимаю, как настроить KVO для одного NSManagedObject, но я не уверен, как это сделать для объекта, содержащегося в массиве. Я понимаю, что могу использовать другой NSFetchedResultsController, но мой self.locations объект не управляет вторым UITableView, поэтому я не уверен, что это имеет смысл.

1 Ответ

10 голосов
/ 21 марта 2012

Довольно просто наблюдать отношение «один ко многим», если все, что вы хотите знать, если объекты добавлены, удалены, заменены или переупорядочены.Фактически, это делается точно так же, как и с обычным объектом:

[self addObserver:self
       forKeyPath:@"locations"
          options:0
          context:NULL];

Затем выполните следующее для получения уведомлений (частично скопированных из документов Apple):

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {

    if ([keyPath isEqual:@"locations"]) {
        // Your custom code here.
    }

    // Be sure to call the superclass's implementation *if it implements it*.
    [super observeValueForKeyPath:keyPath
                         ofObject:object
                           change:change
                           context:context];
}

Донне забудьте прекратить наблюдения в какой-то момент:

[self removeObserver:self forKeyPath:@"locations"];

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

РЕДАКТИРОВАТЬ

Согласно вашему комментарию,Вы хотите наблюдать за отдельными объектами.Это довольно просто для «нормальных» объектов, но управляемый объект требует немного больше работы, потому что вы должны наблюдать отдельные ключи в объекте, которые будут выглядеть примерно так:

- (void)observeManagedObject:(NSManagedObject *)myObject {
    NSArray *myObjectKeys = [[[myObject entity] attributesByName] allKeys];
    for (NSString *key in myObjectKeys) {
        [myObject addObserver:self 
                    forKeyPath:key 
                       options:0 
                       context:nil];
    }
}

Изатем вы наблюдаете все NSManagedObjects в массиве следующим образом:

for (NSManagedObject *object in myArray) {
    [self observeManagedObject:object];
}

Сделайте обратное, чтобы прекратить наблюдать ключи на управляемом объекте!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...