2013-03-27 12 views
9

Hallo alle Jahre StackOverflow lesen, jetzt habe ich mich entschieden, beizutreten. Ich habe Mühe, um dies zu lösen:KVO addObserver zu CoreData-Objekt Eins-zu-viele-Beziehung

Ich habe eine "Depot" -Entität, die zwei zu viele Beziehungen "Personen" und "Trucks" hat. Ich möchte beobachten, wenn es bei einem "Depot" -Objekt Änderungen (einfügen, entfernen) in einer der Beziehungen gibt (und verstehen, in welcher).

i dieser Zeit tue:

[mydepot addObserver:self forKeyPath:@"Trucks" options:NSKeyValueObservingOptionNew context:nil];

und

[mydepot addObserver:self forKeyPath:@"Persons" options:NSKeyValueObservingOptionNew context:nil];

aber jedes Mal etwas in einer der beiden verwandten Sammlungen ändert, wird observeValueForKeyPath zweimal (einmal für jede genannt Schlüsselpfad).

Mache ich es falsch? Wenn man auf "change" dict schaut, (beobachtet auch mit OptionOld) zeigt es keine unerwarteten Änderungen an (wenn ich Personen wechsle, wird Trucks nicht geändert), aber die Benachrichtigung wird immer noch erhöht.

Danke, Pietro

edit: es scheint, dass beide Male die „Veränderung“ dict die gesamte Beziehung in der „neuen“ Feld enthält. (offensichtlich einmal Personen und einmal Trucks)

edit2: wie es passiert, sogar bserving einfache Eigenschaften, könnte es mit dem managedctx speichern Vorgang verbunden sein? als ob, wenn Sie speichern, wird das gesamte Objekt als geändert betrachtet.

Antwort

3

Wenn Sie LKWs atomar setzen (something.trucks = newArray), erhalten Sie eine Wertsatzbenachrichtigung. Verwenden Sie stattdessen addObject/removeObject für das veränderbare Array, das von [ something mutableArrayValueForKey:@"trucks" ] zurückgegeben wird.

Sie können auch die KVO verwenden/Arbeitsgeräte erzeugt Accessoren insertObjectIntoTrucks:/countOfTrucks usw.

Sie sollten die KVO-Dokumentation lesen. Unter "Indizierte Beziehung zu vielen Beziehungen" und "Nicht geordnete Beziehung zu vielen Beziehungen" here.

+1

+1 Zustimmen. Denken Sie daran, die vorhandene Sammlung von Werten zu ändern, anstatt die gesamte Sammlung durch eine andere Sammlung zu ersetzen. – Caleb

+0

Danke, yeah aber Depot ist eine CoreData NSManagedObject-Unterklasse und sollte daher bereits KVO-kompatible Accessoren implementieren. Und ich tue das, was du sagst. Aus Gründen der Fakten füge ich der Beziehung nur eine neue LKW-Entität hinzu und ersetze niemals das gesamte Set (Beziehung). Deshalb kann ich es nicht verstehen. Als ob ich für zwei Schlüsselpfade beobachten würde, zum Beispiel "Trucks" und "sqmeters" (das ist keine Beziehung), wenn "sqmeters" geändert wird, werden zwei Benachrichtigungen ausgelöst (auch eine für die "LKWs" kpath) – Peterdeka

+0

Schlüsselpfade können davon abhängen einander ... vielleicht ist das was passiert? Sonst müssen Sie woanders suchen – nielsbot

9

Im Schlüsselwert Beobachten Programming Guide heißt es, dass

Wenn Sie Core Data verwenden, können Sie die Eltern mit dem Notification Center als Beobachter seiner verwalteten Objektkontext der Anwendung registrieren. Der Elternteil sollte auf relevante Änderungsbenachrichtigungen reagieren, die von den Kindern auf ähnliche Weise wie bei der Schlüsselwertbeobachtung gesendet werden.

Das könnte effektiv bedeuten, dass die empfohlene Praxis ist nicht addObserver:forKeyPath:options:context:, zu verwenden, sondern auch für die NSManagedObjectContextDidSaveNotification statt registrieren.

+0

Ja, das ist meine zweite Wahl, weil ich nur ein Objekt zu einer Zeit habe, das ich beobachten möchte (aber mehrere, die im Hintergrund geändert werden können), ich denke, dass dies eine Verschwendung von Benachrichtigungen ist, da ich für alle Änderungen benachrichtigt werde Objekte und müssen die Notfictions – Peterdeka

+1

@Peterdeka filter das ist immer noch die beste und richtige Antwort. Du solltest es akzeptieren. – Mundi

1

Ich komme mit dem gleichen Problem. Und ich bleibe immer noch bei diesem Problem.

Aber was ich sicher bin, ist, dass der Grund des ersten Mal aufgerufen werden, ist, dass Sie so etwas wie [Depot addPerson:person] während der Grund der zweiten Mal aufgerufen werden, tun die MOC Aktion sparen Posten NSManagedObjectContextDidSaveNotification Benachrichtigung, die Ihre lassen Beobachter denken, dass eine andere Änderung einfach passiert.

Und was ist schlimmer in meinem Problem ist, dass wegen des Beobachters, ich werde einige meiner Änderungen der Kerndaten verloren.

Dadurch fühle ich mich fast zwei Tage lang so dumm.

Ich denke Antwort verwenden registrieren NSManagedObjectContextDidSaveNotification in @Mundi ‚s

Und wenn jemand eine bessere Art und Weise haben, lassen Sie es mich wissen, so schnell wie möglich

0

ich einige Caches gehalten um als Eigenschaften eines NSManagedObject und benötigt, um diese zu entkräften. Ich schaute zuerst in KVO und höre auf NSManagedObjectContextDidSaveNotification.

Die einfachste Lösung für mich war, die Methoden – [NSManagedObject didSave] und – [NSManagedObject didTurnIntoFault] so zu implementieren.

@interface BazClass() 
@property (nonatomic, strong) NSArray* sortedItems; // sorted items cache 
@end 

@implementation BazClass 

@dynamic items; // this is a to many relationship. i.e. NSOrderedSet 
@synthesize sortedItems; 

- (NSArray*)sortedItems 
{ 
    if (!_sortedItems) { 
     NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"foo" ascending:YES]; 
     _sortedItems = [self.items sortedArrayUsingDescriptors:@[sortDescriptor]]; 
    } 
    return _sortedItems; 
} 

// didSave and didTurnIntoFault will delete the sorted items cache 
- (void) didSave 
{ 
    self.sortedItems = nil; 
} 

-(void) didTurnIntoFault 
{ 
    self. sortedItems = nil; 
} 
Verwandte Themen