How do you signal an update for readonly @property, which depends on the properties of children?

This is a simplified example that should be sufficient for the question.

@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

In my example, nothing related to the hasSomethingvalue is reported properly. What am I missing?

+5
source share
2 answers

My workaround: At first I worked on the problem, binding directly to the value that I wanted to track. In the above example, it would look like arrangedObjects.owner.stuff.

: , , , . , ( , , ). : MyClass → Person. . .


-automaticallyNotifiesObserversForKey:, . , , NO , setter . .

- (void)setHasSomething:(BOOL)newVal
{
    [self willChangeValueForKey:@"hasSomething"];
    // ...
    [self didChangeValueForKey:@"hasSomething"];
}

setter readonly, .


: 1) ; 2) .

+3

https://developer.apple.com/library/ios/DOCUMENTATION/Cocoa/Conceptual/KeyValueObserving/Articles/KVOCompliance.html#//apple_ref/doc/uid/20002178-SW3

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey {

    BOOL automatic = NO;
    if ([theKey isEqualToString:@"hasSomething"]) {
        automatic = NO;
    } else {
        automatic=[super automaticallyNotifiesObserversForKey:theKey];
    }
    return automatic;
}
+2

All Articles