Skip to content

Instantly share code, notes, and snippets.

@ddeville
Created October 22, 2013 09:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ddeville/7097600 to your computer and use it in GitHub Desktop.
Save ddeville/7097600 to your computer and use it in GitHub Desktop.
The correct way to react to changes on observed objects.
//
// 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