2012-02-28 4 views
5

To jest uproszczony przykład, który powinien wystarczyć na pytanie.Jak sygnalizować aktualizację tylko do odczytu, która zależy od właściwości podrzędnych?

@interface MyClass: NSObject { 
    Person *_owner; 
} 
    @property (strong) Person *owner; 
    @property (readonly) BOOL hasSomething; 
@end 

@implementation 
    // other code here like -init 
    - (void)setOwner:(Person *)newOwner 
    { 
     [_owner removeObserver:self forKeyPath:@"stuff"]; 
     _owner = newOwner; 
     [_owner addObserver:self forKeyPath:@"stuff" options:0 context:NULL]; 
    } 
    - (Person*)owner 
    { 
     return _owner; 
    } 
    - (BOOL)hasSomething 
    { 
     return owner.stuff > 0; 
    } 
    - (void)observeValueForKeyPath:(NSString*)kp ofObject:(id)obj change:(NSDictionary*)ch context:(void*)c 
    { 
     if ([kp isEqualtToString:@"stuff"]) { 
      [self willChangeValueForKey:@"hasSomething"]; 
      [self didChangeValueForKey:@"hasSomething"]; 
     } 
    } 
@end 

W moim przykładzie, cokolwiek związany hasSomething nie został prawidłowo powiadomiony o zmianie wartości. czego mi brakuje?

Odpowiedz

3

Moja obejście: początkowo pracował wokół kwestii poprzez wiązanie prosto do wartości, które chciałem śledzić. W podanym przykładzie wyglądałoby to tak: arrangedObjects.owner.stuff.

Moje rozwiązanie: I później powrócił kod i odkryli, że co miałem był zasadniczo poprawny. Pomysł polegał na hermetyzowaniu wewnętrznego działania hierarchii obiektów (co nie jest możliwe, jeśli powiążesz całą ścieżkę, tak jak moje obejście powyżej). W pytaniu uprościłem problem do hierarchii o dwóch poziomach: MyClass -> Person. Mój kod faktycznie obejmuje więcej poziomów i wiele relacji. Jednym z elementów hierarchii nie była odpowiednia obserwacja jego dzieci.


Denis zasugerował, żebym spojrzał na -automaticallyNotifiesObserversForKey: i zrobiłem to. Z mojego rozumowania, chciałbyś, aby metoda zwracała NO w przypadku, gdy chcesz ręcznie wysłać powiadomienie w ramach metody ustawiającej właściwość. W przeciwnym razie Twoje powiadomienia będą w konflikcie z automatycznymi.

Ponieważ nie istnieje metoda ustawiająca dla właściwości tylko do odczytu, nie rozwiązała ona mojego problemu.


Wyciągnięte wnioski: 1) Obserwuj prawidłowo swoje dzieci; 2) Nie upraszczaj swojego problemu, gdy prosisz o pomoc.