Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

For mobile 5/13'

528 views

Published on

  • Be the first to comment

  • Be the first to like this

For mobile 5/13'

  1. 1. Multi-Level KVOJakub Hladík
  2. 2. Jakub Hladíkjakub@hippotaps.com@ku33ing, @hippotapsiOS app developerhippotaps co-founderiOS teacher at FIT CTU Prague
  3. 3. Key-Value ObservingWhat?• Key-value observing is a mechanism thatallows objects to be notified of changes tospecified properties of other objects.• alternatives you should already know:• delegate/protocol• NSNotification• callback using @selector or block9
  4. 4. Key-Value Coding First• mechanism that allows accessing objectproperties indirectly by a name/key (string)• NSKeyValueCoding protocol• NSObject provides default implementation(getters/setters, …)10
  5. 5. KVC How?- (id)tableView:(NSTableView *)tableviewobjectValueForTableColumn:(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
  6. 6. KVC How?- (id)tableView:(NSTableView *)tableviewobjectValueForTableColumn:(id)column row:(NSInteger)row{ChildObject *child = [childrenArray objectAtIndex:row];return [child valueForKey:[column identifier]];}12
  7. 7. 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 totraverse13
  8. 8. Getting/SettingAttributes– valueForKey:– valueForKeyPath:– dictionaryWithValuesForKeys:– valueForUndefinedKey:…– setValue:forKeyPath:– setValuesForKeysWithDictionary:– setNilValueForKey:– setValue:forKey:– setValue:forUndefinedKey:…14
  9. 9. Getting/SettingAttributes@interface MyClass@property NSString *stringProperty;@property NSInteger integerProperty;@property MyClass *linkedInstance;@endMyClass *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
  10. 10. Finally KVO– observeValueForKeyPath:ofObject:change:context:– addObserver:forKeyPath:options:context:– removeObserver:forKeyPath:– removeObserver:forKeyPath:context:…– willChangeValueForKey:– didChangeValueForKey:– willChange:valuesAtIndexes:forKey:– didChange:valuesAtIndexes:forKey:…16
  11. 11. KVO17
  12. 12. KVO18
  13. 13. Simple Observing[self setValue:[[self randomPhoneArray] mutableCopy]forKey:@"dataArray"];// self.dataArray = [[self randomPhoneArray] mutableCopy];- (void)observeValueForKeyPath:(NSString *)keyPathofObject:(id)objectchange:(NSDictionary *)changecontext:(void *)context{if ([keyPath isEqualToString:@"dataArray"]) {self.dataArray = change[NSKeyValueChangeNewKey];[self.tableView reloadData];}}19
  14. 14. DemoSimple ObservingHPT-Multi-Level-KVObranch stage120
  15. 15. NSMutableArrayObserving- (void)insertDataObject:(id)objectatIndex:(NSUInteger)index{[self willChange:NSKeyValueChangeInsertionvaluesAtIndexes:[NSIndexSet indexSetWithIndex:index]forKey:@"dataArray"];[self.dataArray insertObject:objectatIndex:index];[self didChange:NSKeyValueChangeInsertionvaluesAtIndexes:[NSIndexSet indexSetWithIndex:index]forKey:@"dataArray"];}21
  16. 16. NSMutableArrayObserving- (void)removeDataObjectAtIndex:(NSUInteger)index{[self willChange:NSKeyValueChangeRemovalvaluesAtIndexes:[NSIndexSet indexSetWithIndex:index]forKey:@"dataArray"];[self.dataArray removeObjectAtIndex:index];[self didChange:NSKeyValueChangeRemovalvaluesAtIndexes:[NSIndexSet indexSetWithIndex:index]forKey:@"dataArray"];}22
  17. 17. NSMutableArrayObserving- (void)observeValueForKeyPath:(NSString *)keyPathofObject:(id)objectchange:(NSDictionary *)changecontext:(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
  18. 18. DemoNSMutableArray ChangeObservingHPT-Multi-Level-KVObranch stage224
  19. 19. Array ObservingSimpler- (void)insertDataObject:(id)objectatIndex:(NSUInteger)index{NSMutableArray *array = [selfmutableArrayValueForKey:@"dataArray"];[array insertObject:object atIndex:index];}- (void)removeDataObjectAtIndex:(NSUInteger)index{NSMutableArray *array = [selfmutableArrayValueForKey:@"dataArray"];[array removeObjectAtIndex:index];}25
  20. 20. DemoNSMutableArray ChangeObserving Done BetterHPT-Multi-Level-KVObranch stage326
  21. 21. Nested ObjectObserving• NSMutableArray in NSMutableArray ):• Not possible without ugly hacks…• NSNotifications… (:[[NSNotificationCenter defaultCenter]postNotificationName:@"objectInsertedAtIndexPath"object:selfuserInfo:@{ @"object" : object,@"indexPath" : indexPath}];27
  22. 22. Multi-LevelDemoNested NSMutableArray ChangeObserving using NSNotificationHPT-Multi-Level-KVObranch stage428
  23. 23. Is That It?29
  24. 24. No Way!30- (id)valueForUndefinedKey:(NSString *)key{NSUInteger i = [key integerValue];return self.dataArray[i];}
  25. 25. 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:NSKeyValueChangeInsertionvaluesAtIndexes:[NSIndexSet indexSetWithIndex:indexPath.row]forKey:[@(indexPath.section) description]];NSMutableArray *array = self.dataArray[indexPath.section];[array insertObject:object atIndex:indexPath.row];[self didChange:NSKeyValueChangeInsertionvaluesAtIndexes:[NSIndexSet indexSetWithIndex:indexPath.row]forKey:[@(indexPath.section) description]];}31
  26. 26. Observer Change 1- (void)addObserverForKey:(NSString *)key{[[HPTDataService sharedService] addObserver:selfforKeyPath:keyoptions:NSKeyValueObservingOptionNewcontext:NULL];}- (void)removeObserverForLastKey{[[HPTDataService sharedService] removeObserver:selfforKeyPath:[@(self.dataArray.count-1) description]context:NULL];}32
  27. 27. 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
  28. 28. Final WorkingMulti-LevelKVO DemoYEAH!HPT-Multi-Level-KVObranch stage534
  29. 29. The End• Key-Value Observing Programming Guide• Key-Value Coding Programming Guide• https://github.com/kubbing/HPT-Multi-Level-KVO• http://www.slideshare.net/JakubHladk/for-mobile-51335

×