2008-09-24 9 views
11

Apple's documentation on -setPrimitiveValue:forKey: jest niejasny na dwa sposoby, gdy używa go do zarządzania relacjami wiele-wiele.setPrimitiveValue: forKey: and to-many relationships

pierwsze stwierdzają:

Jeśli spróbujesz ustawić relację do wielu do nowego obiektu NSMutableSet, to będzie (w końcu) nie powiedzie się.

W końcu ?! Co to ma znaczyć? Czy później zawiedzie podczas -[NSManagedObjectContext save:]? Kiedy obiekt zarządzany jest przekształcany w błąd, a następnie ponownie wywoływany? Gdy? Czy mogę napisać przypadek testowy, aby konsekwentnie odtwarzać awarię na żądanie?

drugie, zapewnienie przykładowy kod, aby prawidłowo obsługiwać tę sprawę, piszą:

najpierw uzyskać istniejącego zestawu używając primitiveValueForKey: (zapewnienia metody nie zwraca nil)

co mam zrobić jeśli/kiedy metoda zwraca zero? assert() i to natychmiast, ponieważ oznacza to, że cały wykres obiektów jest uszkodzony, a zapisanie spowoduje utratę danych? NSAssert() na to jako ostrzeżenie dla dzwoniącego, ale naciśnij (cicho nic nie robiąc)?

Teraz jestem po prostu bezpośrednio przypisywania mój pożądany NS[Mutable]Set w tym przypadku, tak jak poniżej:

- (void)setChildren:(NSSet*)value_ { 
    NSMutableSet *mutableRelationshipSet = [[[self primitiveValueForKey:@"children"] mutableCopy] autorelease]; 
    if (mutableRelationshipSet) { 
     [mutableRelationshipSet setSet:value_]; 
     [self setPrimitiveValue:mutableRelationshipSet forKey:@"children"]; 
    } else { 
     [self setPrimitiveValue:value_ forKey:@"children"]; 
    } 
} 

Czy to źle?

Odpowiedz

6

Po prostu zmodyfikuj zwracaną wartość -primitiveValueForKey: jako zmienny zestaw, ufając, że jego wartość zwracana będzie właściwa.

Pamiętaj też o używaniu -willChangeValueForKey:withSetMutation:usingObjects: i -didChangeValueForKey:withSetMutation:usingObjects: wokół manipulacji; nie pokazałeś tego w powyższym kodzie.

- (void)setChildren:(NSSet *)value { 
    [self willChangeValueForKey:@"children" withSetMutation:NSKeyValueSetSetMutation usingObjects:value]; 

    NSMutableSet *primitiveValue = [self primitiveValueForKey:@"children"]; 

    [primitiveValue setSet:value]; 

    [self didChangeValueForKey:@"children" withSetMutation:NSKeyValueSetSetMutation usingObjects:value]; 
} 

Jeśli możesz kierować reklamy na Leoparda, nie musisz się tym martwić; można użyć Rdzeń danych wbudowanego wsparcia własności Zamiast:

#import <CoreData/CoreData.h> 

@interface Folder : NSManagedObject 
@property (readwrite, retain) NSSet *children; 
@end 

@implementation Folder 
@dynamic children; 
@end 

Rdzeń danych wygeneruje nie tylko getter/setter parę dla właściwości children ale zmienny ustawionych dostępowych, tak więc można użyć -mutableSetValueForKey: na nim i manipulować wynikiem z minimalnym narzutem.