7

Mam NSManagedObject z dwóch właściwości:Autoupdating NSManagedObject modyfikacja właściwość timestamp

NSNumber *score; 
NSDate *score_timestamp; 

Chcę moje score_timestamp pola mają być aktualizowane za każdym razem aktualizować score.

Oczywiście nie mogę użyć metody -willSave, ponieważ mój kontekst jest zapisywany od czasu do czasu, a score_timestamp nie będzie aktualny. Tak więc powinienem zastąpić -setScore: lub ustawić mój obiekt zarządzany jako obserwator klucz-wartość dla jego własnego pola score.

Rozwiązanie -setScore: wydaje się prosta:

- (void) setScore:(NSNumber *)score 
{ 
    [self willChangeValueForKey:@"score"]; 
    [self setPrimitiveScore:score]; 
    [self didChangeValueForKey:@"score"]; 

    self.score_timestamp = [NSDate date]; 
} 

Czy są jakieś zastrzeżenia w robienie rzeczy w ten sposób? Czy powinienem użyć rozwiązania KVO?

Aktualizacja

Dotychczas Dostałem dwie odpowiedzi, że mój kod nie będzie działać poprzez setValue: forKey: i nadal czekam na przykład. Naive dzwoni [(NSManagedObject *)myObject setValue:value forKey:@"score"] dzwoni do mojego setera.

Więc jeśli przejdę do rozwiązania KVO, czy powinienem addObserver: we wszystkich metodach awake i usunąć go w willTurnIntoFault? Czy to nie jest takie proste?

+0

Poważnie, oba programy odpowiadające stwierdzające, że wartość setValue ... nie będą działać, są nieprawidłowe. Możesz to przetestować dość trywialnie, umieszczając punkt przerwania w swoim akcesorium, a następnie zmieniając wartość za pomocą metody setValue. – jrturton

+0

@jrturton Już testowałem to, to na pewno zostanie wywołane. Ale nie jestem ekspertem od Core Data, aby mieć pewność, że istnieje inny sposób zmiany mojej własności bez dostępu. Mam na myśli sposób, w jaki można używać od czasu do czasu w prawdziwym kodzie. – iHunter

+0

Nie. Wszystkie podstawowe połączenia danych będą przechodzić przez twój ustawnik (prawdopodobnie najpierw za pomocą setValueForKey). To część zasady enkapsulacji. Mógłbyś mieć jakiś dziwaczny bezpośredni dostęp do ivar, ale to musiałoby być coś, co sam napisałbyś, co prawdopodobnie również złamałoby kontekst obiektu zarządzanego. Nie zrobiłbyś tego sobie, prawda? – jrturton

Odpowiedz

4

Wdrażanie na twoje pytanie jest w porządku. Każda próba zaktualizowania wartości przez KVC będzie również odbywać się za pomocą metody ustawiającej (setValue: forKey: po prostu szuka metody dostępowej pasującej do setKey, patrz: here).

+2

Widzę "Nie możesz przesłonić tej metody" w "NSManagedObject -didChangeValue:" documentation! – iHunter

+0

To doskonały punkt! Lepiej wymyślę lepszą odpowiedź ... – jrturton

+0

Edytowałem twoją odpowiedź, ponieważ zaczęło dostawać +1, będąc niebezpiecznym. Dziękuję za twój wysiłek, aby mi pomóc, wyrazić moją wdzięczność. Odpowiedziałem na niektóre pytania na inne pytania (one też bardzo pomagają). – iHunter

0

W tej metodzie, jeśli z jakiegokolwiek powodu modyfikuje się obiekt nie jako własną podklasę, ale jako NSManagedObject przy użyciu data nie zostanie zaktualizowana.

+0

Czy możesz podać przykład? – iHunter

1

Szukacie Key-Value Observing

[objectWithArray addObserver:self 
        forKeyPath:@"score" 
        options:NSKeyValueObservingOptionNew 
        context:nil]; 

Następnie, aby go przestrzegać:

-(void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context 
{ 
    //Check if [change objectForKey:NSKeyValueChangeNewKey] is equal to "score" 
    //and update the score_timestamp appropriately 
} 

Należy zarejestrować się na powiadomienia kiedy budzisz od pobierania i wyrejestrować kiedy zarzucić, wierzę.

+0

Tak, KVO jest dobrym rozwiązaniem, ale nie widzę problemu w istniejącym kodzie. Podejrzewam, że ustawienie innej właściwości w ustawieniu nie jest dobrym pomysłem, ale chcę wiedzieć dlaczego, ponieważ widzę, że to działa :) – iHunter

+0

Jeśli możesz zagwarantować, że twój kod będzie używał tylko dynamicznie generowanego gettera/settera dla tej właściwości, twój kod powinien działać, ale jeśli kiedykolwiek użyjesz setValue: forKey: znacznik czasu nie zostanie zaktualizowany. –

+1

@iHunter - nic złego w ustawianiu innej własności w setera. Nie różni się od ustawiania go w jakimkolwiek innym kodzie. Gdybyś ustawiał właściwość _same_, miałbyś kłopoty, ale tak nie jest. – jrturton