2009-07-25 3 views
1

Wenn wir ein Objekt haben, das eine Eigenschaft hat, die basierend auf anderen Eigenschaften generiert wird, implementieren wir normalerweise die Klassenmethode +keyPathsForValuesAffecting{PropertyName}.Wie kann ich einem (verwalteten) Objekt mitteilen, dass es seine KVOs benachrichtigen soll, dass eine seiner Eigenschaften erneut zwischengespeichert werden muss?

Was ich versuche zu tun, ist im Grunde dasselbe für eine Eigenschaft auf meinem NSManagedObject, aber eine Beziehung durchlaufen.

Mein Modell ist einfach; Ich habe zwei Entitäten, App und Version (ich erstelle eine appcast-generierende App). Wenn die Eigenschaften der App geändert werden, weil ich die obige Methode implementiert habe, wird die Zeichenfolge -appcast geändert und alle Bindungen werden entsprechend aktualisiert.

Wenn sich jedoch Eigenschaften in einer bestimmten App-Version (to-many-Beziehung) ändern, wird die Eigenschaft -appcast nicht ordnungsgemäß generiert. Ich kann das Problem beheben/umgehen?

+1

Um klar zu sein: 'appCast' ist eine Eigenschaft auf' App', und wenn Sie die Werte auf einer 'Version' ändern (die vermutlich von' App' über eine 'versions'-Eigenschaft oder ähnlichem verknüpft ist),' appCast 'Eigenschaft sendet keine Änderungsbenachrichtigung? – Alex

Antwort

3

Dies ist ein bisschen eine späte Antwort, aber ich denke, es ist eine häufige Situation, und die Antwort ist definitiv nicht offensichtlich.

Ich schaue im Allgemeinen nach dem ManagedObjectContext, um zu ändern und dann zu überprüfen, ob die geänderten Objekte diejenigen sind, nach denen ich Ausschau halten möchte. Also, in Ihrer NSManagedObject Unterklasse:

// We need to register for the notification in both awakeFromFetch 
// AND awakeFromInsert, since either one could be called, depending on 
// if the object was previously-created or not 
- (void)awakeFromFetch { 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidChange:) name: NSManagedObjectContextObjectsDidChangeNotification object:[self managedObjectContext]]; 
} 

- (void)awakeFromInsert { 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidChange:) name: NSManagedObjectContextObjectsDidChangeNotification object:[self managedObjectContext]]; 
} 

- (void)managedObjectContextDidChange:(NSNotification *)notification { 
    // Get a set containing ALL objects which have been changed 
    NSSet *insertedObjects = [[notification userInfo] objectForKey:NSInsertedObjectsKey]; 
    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey]; 
    NSSet *deletedObjects = [[notification userInfo] objectForKey:NSDeletedObjectsKey]; 

    NSSet *changedObjects = [insertedObjects setByAddingObjectsFromSet:updatedObjects]; 
    changedObjects = [changedObjects setByAddingObjectsFromSet:deletedObjects]; 

    if ([changedObjects intersectsSet:[self versions]]) { 
     [self willChangeValueForKey:@"appCast"]; 
     [self didChangeValueForKey:@"appCast"]; 
    } 
} 

Das ist sicher nicht ideal aus Sicht der Leistung, da diese Meldung jedes Mal etwas in Ihrem Objekt Diagramm, das Änderungen Feuer geht, aber ich habe es gefunden die meisten zu sein einfacher Weg, dies zu erreichen.