Created
October 22, 2013 09:21
-
-
Save ddeville/7097600 to your computer and use it in GitHub Desktop.
The correct way to react to changes on observed objects.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.m | |
// KVO | |
// | |
// Created by Damien DeVille on 10/22/13. | |
// Copyright (c) 2013 Damien DeVille. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
#define CORRECT_KVO 0 | |
@interface Stalked : NSObject | |
@property (assign, nonatomic) NSInteger tag; | |
@end | |
@implementation Stalked | |
@end | |
#pragma mark - | |
@interface Parent : NSObject | |
{ | |
@protected | |
Stalked *_stalked; | |
} | |
@property (strong, nonatomic) Stalked *stalked; | |
@end | |
@implementation Parent | |
static NSString * _ParentStalkedTagContext = @"_ParentStalkedTagContext"; | |
- (id)init | |
{ | |
self = [super init]; | |
if (self == nil) { | |
return nil; | |
} | |
_stalked = [[Stalked alloc] init]; | |
[_stalked addObserver:self forKeyPath:@"tag" options:(NSKeyValueObservingOptions)0 context:&_ParentStalkedTagContext]; | |
return self; | |
} | |
- (void)dealloc | |
{ | |
[_stalked removeObserver:self forKeyPath:@"tag" context:&_ParentStalkedTagContext]; | |
} | |
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context | |
{ | |
#if CORRECT_KVO | |
if (context == &_ParentStalkedTagContext) { | |
NSLog(@"Parent"); | |
} | |
#else | |
if ([keyPath isEqualToString:@"tag"]) { | |
NSLog(@"Parent"); | |
} | |
#endif /* CORRECT_KVO */ | |
else { | |
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; | |
} | |
} | |
@end | |
#pragma mark - | |
@interface Child : Parent | |
@end | |
@implementation Child | |
static NSString * _ChildStalkedTagContext = @"_ChildStalkedTagContext"; | |
- (id)init | |
{ | |
self = [super init]; | |
if (self == nil) { | |
return nil; | |
} | |
[_stalked addObserver:self forKeyPath:@"tag" options:(NSKeyValueObservingOptions)0 context:&_ChildStalkedTagContext]; | |
return self; | |
} | |
- (void)dealloc | |
{ | |
[_stalked removeObserver:self forKeyPath:@"tag" context:&_ChildStalkedTagContext]; | |
} | |
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context | |
{ | |
#if CORRECT_KVO | |
if (context == &_ChildStalkedTagContext) { | |
NSLog(@"Child"); | |
} | |
#else | |
if ([keyPath isEqualToString:@"tag"]) { | |
NSLog(@"Child"); | |
} | |
#endif /* CORRECT_KVO */ | |
else { | |
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; | |
} | |
} | |
@end | |
#pragma mark - | |
int main(int argc, const char **argv) | |
{ | |
Child *child = [[Child alloc] init]; | |
[[child stalked] setTag:2]; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment