For mobile 5/13'
-
Upload
jakub-hladik -
Category
Documents
-
view
285 -
download
3
Transcript of For mobile 5/13'
![Page 1: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/1.jpg)
Multi-Level KVOJakub Hladík
![Page 2: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/2.jpg)
Jakub Hladí[email protected]
@ku33ing, @hippotaps
iOS app developerhippotaps co-founder
iOS teacher at FIT CTU Prague
![Page 3: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/3.jpg)
![Page 4: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/4.jpg)
![Page 5: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/5.jpg)
![Page 6: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/6.jpg)
![Page 7: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/7.jpg)
![Page 8: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/8.jpg)
![Page 9: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/9.jpg)
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 10: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/10.jpg)
Key-Value Coding First
• mechanism that allows accessing object properties indirectly by a name/key (string)
• NSKeyValueCoding protocol
• NSObject provides default implementation (getters/setters, …)
10
![Page 11: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/11.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/12.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/13.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/14.jpg)
Getting/Setting Attributes
– valueForKey:– valueForKeyPath:– dictionaryWithValuesForKeys:– valueForUndefinedKey:…
– setValue:forKeyPath:– setValuesForKeysWithDictionary:– setNilValueForKey:– setValue:forKey:– setValue:forUndefinedKey:…
14
![Page 15: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/15.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/16.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/17.jpg)
KVO
17
![Page 18: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/18.jpg)
KVO
18
![Page 19: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/19.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/20.jpg)
DemoSimple Observing
HPT-Multi-Level-KVObranch stage1
20
![Page 21: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/21.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/22.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/23.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/24.jpg)
DemoNSMutableArray Change
Observing
HPT-Multi-Level-KVObranch stage2
24
![Page 25: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/25.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/26.jpg)
DemoNSMutableArray Change Observing Done Better
HPT-Multi-Level-KVObranch stage3
26
![Page 27: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/27.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/28.jpg)
Multi-Level Demo
Nested NSMutableArray Change Observing using NSNotification
HPT-Multi-Level-KVObranch stage4
28
![Page 29: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/29.jpg)
Is That It?
29
![Page 30: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/30.jpg)
No Way!
30
- (id)valueForUndefinedKey:(NSString *)key{ NSUInteger i = [key integerValue]; return self.dataArray[i];}
![Page 31: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/31.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/32.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/33.jpg)
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'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/34.jpg)
Final Working Multi-Level KVO Demo
YEAH!
HPT-Multi-Level-KVObranch stage5
34
![Page 35: For mobile 5/13'](https://reader033.fdocuments.net/reader033/viewer/2022052600/557d36e9d8b42a585f8b4ad6/html5/thumbnails/35.jpg)
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-513
35