 <blockquote> <p>on the second approach i will get a notification if the 'controller' object on self was replaced</p> </blockquote> <p>I would rephrase by saying that on the second approach you'll get notified if the controller object gets replaced <strong>or if its <code>isEnabled</code> property changes</strong>. In other word when <code>controller.isEnabled</code> changes (as explained by Ken's answer).</p> <p>Check this example:</p> <pre><code>- (void)viewDidLoad { [super viewDidLoad]; self.controller = [[ViewController2 alloc] init]; [self.controller addObserver:self forKeyPath:@"isEnabled" options:NSKeyValueObservingOptionNew context:nil]; [self addObserver:self forKeyPath:@"controller.isEnabled" options:NSKeyValueObservingOptionNew context:nil]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.controller.isEnabled = !self.controller.isEnabled; // replace controller [self.controller removeObserver:self forKeyPath:@"isEnabled"]; self.controller = [[ViewController2 alloc] init]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.controller.isEnabled = !self.controller.isEnabled; }); }); } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { NSLog(@"KVO %d %@ %p", self.controller.isEnabled, keyPath, self.controller); } </code></pre> <p>We'll get 4 KVO notifications:</p> <pre><code>KVO 1 controller.isEnabled 0x7fbbc2e4b4e0 &lt;-- These 2 fire together when we toggle isEnbled KVO 1 isEnabled 0x7fbbc2e4b4e0 &lt;-- So basically 1. and 2. behave the same KVO 0 controller.isEnabled 0x7fbbc2e58d30 &lt;---- controller was replaced KVO 1 controller.isEnabled 0x7fbbc2e58d30 &lt;---- Toggle on the new instance </code></pre>