6

Ho un'app per iPad che ha unche implementa lo NSFetchedResultsControllerDelegate. (Principalmente usando l'CoreDataTableViewControllercode dalle classi Stanford IOS.)Come configurare KVO su una raccolta (NSArray o NSSet) di NSManagedObjects

Ho un oggetto modello secondario (self.locations) che è un array di Location oggetti che è una sottoclasse di NSManagedObjects. Questo array controlla il contenuto di un UISegmentedControl che filtra il mio principale fetchedResultsContoller.

È possibile modificare il contenuto di self.locations tramite un popover. Voglio impostare una sorta di osservazione in modo che il mio UITableViewController principale possa guardare le modifiche negli oggetti memorizzati in self.locations e ricaricare il UISegmentedControl se necessario.

Ciò potrebbe anche comportare un ricaricamento dei dati principali nella tabella, quindi voglio fare attenzione a non ricaricare su ogni piccola modifica.

Penso di aver capito come impostare KVO su un singolo NSManagedObject ma non sono sicuro di come farlo sull'oggetto contenuto in un array. Capisco che posso usare un altro NSFetchedResultsController, ma il mio oggetto self.locations non guida un secondo UITableView, quindi non sono sicuro che abbia senso.

risposta

10

È piuttosto semplice osservare una relazione uno-a-molti se tutto ciò che si desidera sapere se gli oggetti vengono aggiunti, rimossi, sostituiti o riordinati. In realtà, si è fatto esattamente allo stesso modo come con un normale oggetto:

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

quindi implementare il seguente per ricevere le notifiche (parzialmente copiati da documenti di 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]; 
} 

Non dimenticate di smettere di osservazione ad un certo punto:

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

E, anche se non ha chiesto, se volete sapere se uno dei oggetti contenuti nel rel azionalità hanno modificato (e non solo l'NSSet che stai guardando qui), quindi devi osservare i singoli oggetti.

EDIT

Per il tuo commento, si vuole osservare i singoli oggetti. Questo è abbastanza straight-forward per "normali" oggetti, ma un oggetto gestito prende un po 'più di lavoro, perché si deve osservare i singoli tasti in oggetto, che sarebbe simile a questa:

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

E poi si osservare tutte le NSManagedObjects nella matrice come questo:

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

fare il contrario di smettere di osservare i tasti sul oggetto gestito!

+1

Grazie @Inafziger! Questo aiuta molto. – DeepFriedTwinkie

Problemi correlati