+ All Categories
Home > Documents > For mobile 5/13'

For mobile 5/13'

Date post: 14-Jun-2015
Category:
Upload: jakub-hladik
View: 283 times
Download: 3 times
Share this document with a friend
Popular Tags:
35
Multi-Level KVO Jakub Hladík
Transcript
Page 1: For mobile 5/13'

Multi-Level KVOJakub Hladík

Page 3: For mobile 5/13'
Page 4: For mobile 5/13'
Page 5: For mobile 5/13'
Page 6: For mobile 5/13'
Page 7: For mobile 5/13'
Page 8: For mobile 5/13'
Page 9: For mobile 5/13'

Key-Value Observing What?

• Key-value observing is a mechanism that allows objects to be notified of changes to specified properties of other objects.

• alternatives you should already know:

• delegate/protocol

• NSNotification

• callback using @selector or block

9

Page 11: For mobile 5/13'

KVC How?

- (id)tableView:(NSTableView *)tableview objectValueForTableColumn:(id)column row:(NSInteger)row{ ChildObject *child = [childrenArray objectAtIndex:row]; if ([[column identifier] isEqualToString:@"name"]) { return [child name]; }

if ([[column identifier] isEqualToString:@"age"]) { return [child age]; }

if ([[column identifier] isEqualToString:@"favoriteColor"]) { return [child favoriteColor]; }}

11

Page 12: For mobile 5/13'

KVC How?

- (id)tableView:(NSTableView *)tableviewobjectValueForTableColumn:(id)column row:(NSInteger)row{ ChildObject *child = [childrenArray objectAtIndex:row]; return [child valueForKey:[column identifier]]; }

12

Page 13: For mobile 5/13'

KVC Terminology

• properties:

• attributes (scalar, string, NSNumber, …)

• to-one relationships (self.otherObject, self.superView, …)

• to-many relationships (collection of objects – NSArray, NSSet, …)

• key (@”age”) – identifies object property

• path (@”superView.frame”, @”address.street”)

– dot.separated keys specifying a sequence of objects to traverse

13

Page 14: For mobile 5/13'

Getting/Setting Attributes

– valueForKey:– valueForKeyPath:– dictionaryWithValuesForKeys:– valueForUndefinedKey:…

– setValue:forKeyPath:– setValuesForKeysWithDictionary:– setNilValueForKey:– setValue:forKey:– setValue:forUndefinedKey:…

14

Page 15: For mobile 5/13'

Getting/Setting Attributes

@interface MyClass

@property NSString *stringProperty;@property NSInteger integerProperty;@property MyClass *linkedInstance;

@end

MyClass *myInstance = [[MyClass alloc] init];NSString *string = [myInstance valueForKey:@"stringProperty"];[myInstance setValue:@2 forKey:@"integerProperty"];

MyClass *anotherInstance = [[MyClass alloc] init];myInstance.linkedInstance = anotherInstance;[myInstance setValue:@2 forKeyPath:@"linkedInstance.integerProperty"];

15

Page 16: For mobile 5/13'

Finally KVO

– observeValueForKeyPath:ofObject:change:context:

– addObserver:forKeyPath:options:context:– removeObserver:forKeyPath:– removeObserver:forKeyPath:context:…

– willChangeValueForKey:– didChangeValueForKey:– willChange:valuesAtIndexes:forKey:– didChange:valuesAtIndexes:forKey:…

16

Page 17: For mobile 5/13'

KVO

17

Page 18: For mobile 5/13'

KVO

18

Page 19: For mobile 5/13'

Simple Observing[self setValue:[[self randomPhoneArray] mutableCopy] forKey:@"dataArray"];

// self.dataArray = [[self randomPhoneArray] mutableCopy];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ if ([keyPath isEqualToString:@"dataArray"]) { self.dataArray = change[NSKeyValueChangeNewKey]; [self.tableView reloadData]; }}

19

Page 20: For mobile 5/13'

DemoSimple Observing

HPT-Multi-Level-KVObranch stage1

20

Page 21: For mobile 5/13'

NSMutableArray Observing

- (void)insertDataObject:(id)object atIndex:(NSUInteger)index{ [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"dataArray"]; [self.dataArray insertObject:object atIndex:index]; [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"dataArray"];}

21

Page 22: For mobile 5/13'

NSMutableArray Observing

- (void)removeDataObjectAtIndex:(NSUInteger)index{ [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"dataArray"]; [self.dataArray removeObjectAtIndex:index]; [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:[NSIndexSet indexSetWithIndex:index] forKey:@"dataArray"];}

22

Page 23: For mobile 5/13'

NSMutableArray Observing

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ if ([keyPath isEqualToString:@"dataArray"]) { NSIndexSet *set = change[NSKeyValueChangeIndexesKey]; NSKeyValueChange valueChange = [change[NSKeyValueChangeKindKey] unsignedIntegerValue]; NSArray *new = change[NSKeyValueChangeNewKey];

switch (valueChange) { case NSKeyValueChangeInsertion: [self addObject:new.lastObject atIndex:set.lastIndex]; break; case NSKeyValueChangeRemoval: [self removeObjectAtIndex:set.lastIndex]; break; case NSKeyValueChangeSetting: self.dataArray = [new mutableCopy]; [self.tableView reloadData]; break; default: break; } }}

23

Page 24: For mobile 5/13'

DemoNSMutableArray Change

Observing

HPT-Multi-Level-KVObranch stage2

24

Page 25: For mobile 5/13'

Array Observing Simpler

- (void)insertDataObject:(id)object atIndex:(NSUInteger)index{ NSMutableArray *array = [self mutableArrayValueForKey:@"dataArray"]; [array insertObject:object atIndex:index];}

- (void)removeDataObjectAtIndex:(NSUInteger)index{ NSMutableArray *array = [self mutableArrayValueForKey:@"dataArray"]; [array removeObjectAtIndex:index];}

25

Page 26: For mobile 5/13'

DemoNSMutableArray Change Observing Done Better

HPT-Multi-Level-KVObranch stage3

26

Page 27: For mobile 5/13'

Nested Object Observing

• NSMutableArray in NSMutableArray ):

• Not possible without ugly hacks…

• NSNotifications… (:

[[NSNotificationCenter defaultCenter] postNotificationName:@"objectInsertedAtIndexPath" object:self userInfo:@{ @"object" : object, @"indexPath" : indexPath }];

27

Page 28: For mobile 5/13'

Multi-Level Demo

Nested NSMutableArray Change Observing using NSNotification

HPT-Multi-Level-KVObranch stage4

28

Page 29: For mobile 5/13'

Is That It?

29

Page 30: For mobile 5/13'

No Way!

30

- (id)valueForUndefinedKey:(NSString *)key{ NSUInteger i = [key integerValue]; return self.dataArray[i];}

Page 31: For mobile 5/13'

Model Change- (id)valueForUndefinedKey:(NSString *)key{ NSUInteger i = [key integerValue]; return self.dataArray[i];}

- (void)insertDataObject:(id)object atIndexPath:(NSIndexPath *)indexPath{ if (indexPath.section == self.dataArray.count) { [self insertDataObject:[NSMutableArray array] atIndex:indexPath.section]; } [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:indexPath.row] forKey:[@(indexPath.section) description]]; NSMutableArray *array = self.dataArray[indexPath.section]; [array insertObject:object atIndex:indexPath.row]; [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:indexPath.row] forKey:[@(indexPath.section) description]];}

31

Page 32: For mobile 5/13'

Observer Change 1

- (void)addObserverForKey:(NSString *)key{ [[HPTDataService sharedService] addObserver:self forKeyPath:key options:NSKeyValueObservingOptionNew context:NULL];}

- (void)removeObserverForLastKey{ [[HPTDataService sharedService] removeObserver:self forKeyPath:[@(self.dataArray.count-1) description] context:NULL];}

32

Page 33: For mobile 5/13'

Observer Change 2

- (void)addObject:(id)object atIndex:(NSUInteger)index{ [self.dataArray insertObject:object atIndex:index]; [self addObserverForKey:[@(self.dataArray.count-1) description]]; [self.tableView beginUpdates]; [self.tableView insertSections:[NSIndexSet indexSetWithIndex:index] withRowAnimation:UITableViewRowAnimationRight]; [self.tableView endUpdates];}

33

Page 34: For mobile 5/13'

Final Working Multi-Level KVO Demo

YEAH!

HPT-Multi-Level-KVObranch stage5

34


Recommended