Skip to content

Instantly share code, notes, and snippets.

@wisaruthk
Created March 3, 2016 07:10
Show Gist options
  • Save wisaruthk/c53a480e739768c2b10c to your computer and use it in GitHub Desktop.
Save wisaruthk/c53a480e739768c2b10c to your computer and use it in GitHub Desktop.
objc KVO example
//
// Children.h
// KVCODemo
//
// Created by wisaruthk on 3/3/2559 BE.
// Copyright © 2559 kojo. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Children : NSObject
@property(nonatomic,strong) NSString *name;
@property(nonatomic) NSUInteger age;
@property(nonatomic,strong) Children *child;
@property(nonatomic,strong) NSMutableArray *siblings;
-(NSUInteger)countOfSiblings;
-(id)objectInSiblingsAtIndex:(NSUInteger)index;
-(void)insertObject:(NSString *)object inSiblingsAtIndex:(NSUInteger)index;
-(void)removeObjectFromSiblingsAtIndex:(NSUInteger)index;
@end
//
// Children.m
// KVCODemo
//
// Created by wisaruthk on 3/3/2559 BE.
// Copyright © 2559 kojo. All rights reserved.
//
#import "Children.h"
@implementation Children
- (instancetype)init
{
self = [super init];
if (self) {
self.name = @"";
self.age = 0;
self.siblings = [[NSMutableArray alloc] init];
}
return self;
}
+(BOOL)automaticallyNotifiesObserversForKey:(NSString *)key{
if([key isEqualToString:@"name"]){
return NO;
} else {
return [super automaticallyNotifiesObserversForKey:key];
}
}
-(NSUInteger)countOfSiblings{
return self.siblings.count;
}
-(id)objectInSiblingsAtIndex:(NSUInteger)index{
return [self.siblings objectAtIndex:index];
}
-(void)insertObject:(NSString *)object inSiblingsAtIndex:(NSUInteger)index{
[self.siblings insertObject:object atIndex:index];
}
-(void)removeObjectFromSiblingsAtIndex:(NSUInteger)index {
[self.siblings removeObjectAtIndex:index];
}
@end
2016-03-03 14:08:41.103 KVCODemo[55658:19378605] George, 15
2016-03-03 14:08:41.104 KVCODemo[55658:19378605] Andrew, 5
2016-03-03 14:08:41.104 KVCODemo[55658:19378605] The name of the FIRST child was changed.
2016-03-03 14:08:41.104 KVCODemo[55658:19378605] {
kind = 1;
new = Michael;
old = George;
}
2016-03-03 14:08:41.105 KVCODemo[55658:19378605] The age of the FIRST child was changed.
2016-03-03 14:08:41.105 KVCODemo[55658:19378605] {
kind = 1;
new = 20;
old = 15;
}
2016-03-03 14:08:41.105 KVCODemo[55658:19378605] The age of the SECOND child was changed.
2016-03-03 14:08:41.105 KVCODemo[55658:19378605] {
kind = 1;
new = 45;
old = 35;
}
2016-03-03 14:08:41.105 KVCODemo[55658:19378605] {
indexes = "<_NSCachedIndexSet: 0x7fe463d24db0>[number of indexes: 1 (in 1 ranges), indexes: (0)]";
kind = 2;
new = (
Alex
);
}
2016-03-03 14:08:41.106 KVCODemo[55658:19378605] {
indexes = "<_NSCachedIndexSet: 0x7fe463d24e20>[number of indexes: 1 (in 1 ranges), indexes: (1)]";
kind = 2;
new = (
Bob
);
}
2016-03-03 14:08:41.106 KVCODemo[55658:19378605] {
indexes = "<_NSCachedIndexSet: 0x7fe463d24e40>[number of indexes: 1 (in 1 ranges), indexes: (2)]";
kind = 2;
new = (
Mary
);
}
2016-03-03 14:08:41.106 KVCODemo[55658:19378605] {
indexes = "<_NSCachedIndexSet: 0x7fe463d24e20>[number of indexes: 1 (in 1 ranges), indexes: (1)]";
kind = 3;
old = (
Bob
);
}
//
// ViewController.m
// KVCODemo
//
// Created by wisaruthk on 3/3/2559 BE.
// Copyright © 2559 kojo. All rights reserved.
//
#import "ViewController.h"
// Context is a pointer point to it self.
static void *someContext = &someContext;
static void *child1Context = &child1Context;
static void *child2Context = &child2Context;
@interface ViewController ()
@property(nonatomic,strong) Children *child1;
@property(nonatomic,strong) Children *child2;
@property(nonatomic,strong) Children *child3;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.child1 = [[Children alloc] init];
// self.child1.name = @"George";
// self.child1.age = 15;
// ถ้าคียร์ไม่มีจะ Error
[self.child1 setValue:@"George" forKey:@"name"];
[self.child1 setValue:[NSNumber numberWithInteger:15] forKey:@"age"];
NSString *childName = [self.child1 valueForKey:@"name"];
NSUInteger childAge = [[self.child1 valueForKey:@"age"] integerValue];
NSLog(@"%@, %d",self.child1.name,self.child1.age);
self.child2 = [[Children alloc] init];
[self.child2 setValue:@"Mary" forKey:@"name"];
[self.child2 setValue:[NSNumber numberWithInteger:35] forKey:@"age"];
self.child2.child = [[Children alloc] init];
[self.child2 setValue:@"Andrew" forKeyPath:@"child.name"];
[self.child2 setValue:[NSNumber numberWithInteger:5] forKeyPath:@"child.age"];
NSLog(@"%@, %d", self.child2.child.name, self.child2.child.age);
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.child1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:child1Context];
[self.child1 addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:child1Context];
// Manual Notifications
[self.child1 willChangeValueForKey:@"name"];
[self.child1 setValue:@"Michael" forKey:@"name"];
[self.child1 didChangeValueForKey:@"name"];
// Auto Notifications
[self.child1 setValue:[NSNumber numberWithInteger:20] forKey:@"age"];
//
[self.child2 addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:child2Context];
[self.child2 setValue:[NSNumber numberWithInteger:45] forKey:@"age"];
// Array Notif
[self.child1 addObserver:self forKeyPath:@"siblings" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
[self.child1 insertObject:@"Alex" inSiblingsAtIndex:0];
[self.child1 insertObject:@"Bob" inSiblingsAtIndex:1];
[self.child1 insertObject:@"Mary" inSiblingsAtIndex:2];
[self.child1 removeObjectFromSiblingsAtIndex:1];
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if(context == child1Context){
if([keyPath isEqualToString:@"name"]){
NSLog(@"The name of the FIRST child was changed.");
NSLog(@"%@",change);
}
if([keyPath isEqualToString:@"age"]){
NSLog(@"The age of the FIRST child was changed.");
NSLog(@"%@",change);
}
} else if(context == child2Context){
if ([keyPath isEqualToString:@"age"]) {
NSLog(@"The age of the SECOND child was changed.");
NSLog(@"%@", change);
}
} else {
if([keyPath isEqualToString:@"siblings"]){
NSLog(@"%@",change);
}
}
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self.child1 removeObserver:self forKeyPath:@"name"];
[self.child1 removeObserver:self forKeyPath:@"age"];
[self.child2 removeObserver:self forKeyPath:@"age"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment