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.
KVC/KVO and
                 Bindings
               quot;MVC with less codequot;




CocoaHeads México
   27-Nov-2008


 ...
Key Value Coding



                   2
What is it?

• Access properties by name:



• Every class essentially becomes a
  dictionary
• Not a 'trick'. This is fun...
What is it?

    • Access properties by name:
[person name]
[person setName:@quot;Sergioquot;]



    • Every class essent...
What is it?

    • Access properties by name:
[person name]                [person valueForKey:@quot;namequot;]
[person se...
How it works
• NSKeyValueCoding
  (informal) protocol

• Implemented by
  NSObject


• NSKeyValueCoding.h



             ...
Using key value coding




                         5
Code!
Using key value coding




                         5
Accessor lookup




                  6
Accessor lookup
1. Search for a public accessor
   ('getLastName' or 'lastName')




                                   6
Accessor lookup
1. Search for a public accessor
   ('getLastName' or 'lastName')
2. If not found, search for a private
   ...
Accessor lookup
1. Search for a public accessor
   ('getLastName' or 'lastName')
2. If not found, search for a private
   ...
Accessor lookup
1. Search for a public accessor
   ('getLastName' or 'lastName')
2. If not found, search for a private
   ...
No magic!



• KVC uses the runtime information
  generated by the compiler
• Easy to fake...




                        ...
quot;Implementingquot; KVC quot;from scratchquot;




                                    8
Code!
quot;Implementingquot; KVC quot;from scratchquot;




                                    8
Performance?


• Every Objective-C message goes
  through objc_msgSend() anyways
• KVC caches property lookups
• Not likel...
KVC, value types and nil

• Property values are always of type id
  (reference type)
  • structs ➔ NSValue
  • numbers ➔ N...
NSDictionary KVC

• NSDictionary has a custom
  implementation of KVC that
  attempts to match keys against keys
  in the ...
Practical uses of KVC



• Used by UI bindigs
• Key-based archiving (serialization)




                                  ...
More on KVC



              13
Model Validation

• Optional set of validation methods
• Some views call automatically the
  validation methods
  • Import...
Key Paths

• Like file paths (/usr/local/bin)
• Used to traverse an object graph:
  ”document.header.title”
• valueForKeyPa...
Using key paths




                  16
Code!
Using key paths




                  16
KVC and Array properties


• No native support. You cannot pass
  indexes in key paths:
  • valueForKeyPath:@quot;order.it...
Set and array operators
• Arrays and sets support ‘aggregate’ keys:
  • @avg, @count, @max, @min, @sum,
      @distinctUni...
NSPredicates

    • You can build NSPredicates to use
       more complex queries, like And, Or,
       RegExps, method ca...
The secret to KVC
  compliance...




                    20
The secret to KVC
  compliance...


  Just use the correct naming
conventions for your accessors!
   (or Objective-C 2.0 p...
Key Value Observing



                      21
What is it?


• Change notifications to model classes
• Observer pattern
• Based on KVC




                               ...
How it works

• Subscribe:
  • addObserver:forKeyPath:options:context:
  • opitons: NSKeyValueObservingOptionOld
     NSKe...
Important!


• Notification works by replacing your
  accessors.
• This means that direct ivar access will
  not produce no...
Observing with KVO notifications




                                  25
Code!
Observing with KVO notifications




                                  25
Derived properties

• Example: fullName property that
  changes when lastName and firstName
  change
• Implement:
  keyPat...
Manual notifications


• Example: dynamic value that changes
  a lot. Calculated value you only want
  to display at certai...
Manual notifications and derived
          properties




                                  28
Code!
Manual notifications and derived
          properties




                                  28
Careful!

• addObserver:… does not throw an
  exception when you get the keyPath
  wrong.
• If you observe a path with mul...
Observing Array changes
• Difficult. You can't observe them at all
  • (in KVO, only the property is observed,
    not the ...
KVC Accessor selector formats
{property}                   memberOf{property}:
set{property}:               intersect{prop...
Observe array element changes
• You can’t. You have to observe each of
  the elements individually
• Solution: NSArrayCont...
Uses for KVO?
• Coherence between multiple views
  and a model
• Simplifying flow control
• Simplifying undo implementation...
Bindings



           34
What is it?
    “Allows you to establish a mediated
    connection between a view and a piece
    of data, “binding” them ...
Manual binding

• Call:
  bind:toObject:withKeyPath:options:
  on the ‘view’ object
• The ‘view’ will use KVC/KVO
  • KVC ...
Manual bindings




                  37
Code!
Manual bindings




                  37
Binding Controllers


• Basic binding works without controllers!
• Object controller: dumb wrapper around KVO
• Array Cont...
Bindings in IB




                 39
Code!
Bindings in IB




                 39
(if time permits)



                    40
One more thing...
Value Transformers
     (if time permits)



                         40
Goal: Reduce 'glue' code




                           41
Goal: Reduce 'glue' code

• Example: binding an 'enabled' control
  to a 'false' property




                            ...
Goal: Reduce 'glue' code

• Example: binding an 'enabled' control
  to a 'false' property
• Example: showing an image for ...
Goal: Reduce 'glue' code

• Example: binding an 'enabled' control
  to a 'false' property
• Example: showing an image for ...
Available value
        transformers:
•   NSNegateBooleanTransformer
•   NSIsNilTransformer
•   NSIsNotNilTransformer
•   ...
Value Transformers




                     43
Code!
Value Transformers




                     43
Resources

• Introduction to Cocoa Bindings Programming Topics
   (Apple)
• Key Value Coding programming guide (Apple)
• K...
45
The End

          45
Upcoming SlideShare
Loading in …5
×

Intro to Cocoa KVC/KVO and Bindings

34,416 views

Published on

Presentation for the CocoaHeads Mexico City's session from November 28th, 2008.

Published in: Technology
  • Be the first to comment

Intro to Cocoa KVC/KVO and Bindings

  1. 1. KVC/KVO and Bindings quot;MVC with less codequot; CocoaHeads México 27-Nov-2008 1
  2. 2. Key Value Coding 2
  3. 3. What is it? • Access properties by name: • Every class essentially becomes a dictionary • Not a 'trick'. This is fundamental Cocoa programming. 3
  4. 4. What is it? • Access properties by name: [person name] [person setName:@quot;Sergioquot;] • Every class essentially becomes a dictionary • Not a 'trick'. This is fundamental Cocoa programming. 3
  5. 5. What is it? • Access properties by name: [person name] [person valueForKey:@quot;namequot;] [person setName:@quot;Sergioquot;] [person setValue:@quot;Sergioquot; forKey:@quot;namequot;] • Every class essentially becomes a dictionary • Not a 'trick'. This is fundamental Cocoa programming. 3
  6. 6. How it works • NSKeyValueCoding (informal) protocol • Implemented by NSObject • NSKeyValueCoding.h 4
  7. 7. Using key value coding 5
  8. 8. Code! Using key value coding 5
  9. 9. Accessor lookup 6
  10. 10. Accessor lookup 1. Search for a public accessor ('getLastName' or 'lastName') 6
  11. 11. Accessor lookup 1. Search for a public accessor ('getLastName' or 'lastName') 2. If not found, search for a private accessor method based on key ('_getLastName' or '_lastName'). 6
  12. 12. Accessor lookup 1. Search for a public accessor ('getLastName' or 'lastName') 2. If not found, search for a private accessor method based on key ('_getLastName' or '_lastName'). 3. If not found' search for an instance variable (_lastName or lastName) 6
  13. 13. Accessor lookup 1. Search for a public accessor ('getLastName' or 'lastName') 2. If not found, search for a private accessor method based on key ('_getLastName' or '_lastName'). 3. If not found' search for an instance variable (_lastName or lastName) 4. If not found, invoke valueForUndefinedKey: 6
  14. 14. No magic! • KVC uses the runtime information generated by the compiler • Easy to fake... 7
  15. 15. quot;Implementingquot; KVC quot;from scratchquot; 8
  16. 16. Code! quot;Implementingquot; KVC quot;from scratchquot; 8
  17. 17. Performance? • Every Objective-C message goes through objc_msgSend() anyways • KVC caches property lookups • Not likely to be the bottleneck 9
  18. 18. KVC, value types and nil • Property values are always of type id (reference type) • structs ➔ NSValue • numbers ➔ NSNumber • You should implement setNilValueForKey: 10
  19. 19. NSDictionary KVC • NSDictionary has a custom implementation of KVC that attempts to match keys against keys in the dictionary. NSDictionary *dictionary; [dictionary setValue:@quot;Sergioquot; forKey:@quot;namequot;]; 11
  20. 20. Practical uses of KVC • Used by UI bindigs • Key-based archiving (serialization) 12
  21. 21. More on KVC 13
  22. 22. Model Validation • Optional set of validation methods • Some views call automatically the validation methods • Important!: You are not supposed to reject the value in setValue:forKey: • validateValue:forKey:error: automatically calls: validate{property}:error: 14
  23. 23. Key Paths • Like file paths (/usr/local/bin) • Used to traverse an object graph: ”document.header.title” • valueForKeyPath:, setValue:forKeyPath: • Warning!: you cannot pass a keyPath if the selector is just 'forKey:' only to 'forKeyPath:' 15
  24. 24. Using key paths 16
  25. 25. Code! Using key paths 16
  26. 26. KVC and Array properties • No native support. You cannot pass indexes in key paths: • valueForKeyPath:@quot;order.items[1].pricequot; • Ask an array for a key, the array will ask all its elements and return an array of the resulting values. 17
  27. 27. Set and array operators • Arrays and sets support ‘aggregate’ keys: • @avg, @count, @max, @min, @sum, @distinctUnionOfArrays, @distinctUnionOfObjects, @distinctUnionOfSets, @unionOfArrays, @unionOfObjects, @unionOfSets • You can use this aggregate properties to bind to in IB NSNumber *total = [purchaseOrder valueForKeyPath: @quot;@sum.pricequot;]; 18
  28. 28. NSPredicates • You can build NSPredicates to use more complex queries, like And, Or, RegExps, method calling, etc. • Cocoa's 'LINQ' NSArray *severalObjects = [NSArray arrayWithObjects:@quot;Stigquot;, @quot;Shaffiqquot;, @quot;Chrisquot;, nil]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@quot;SELF IN %@quot;, severalObjects]; BOOL result = [predicate evaluateWithObject:@quot;Shaffiqquot;]; 19
  29. 29. The secret to KVC compliance... 20
  30. 30. The secret to KVC compliance... Just use the correct naming conventions for your accessors! (or Objective-C 2.0 properties) 20
  31. 31. Key Value Observing 21
  32. 32. What is it? • Change notifications to model classes • Observer pattern • Based on KVC 22
  33. 33. How it works • Subscribe: • addObserver:forKeyPath:options:context: • opitons: NSKeyValueObservingOptionOld NSKeyValueObservingOptionNew • Unsubscribe: • removeObserver:forKeyPath: • Receive notification: • observeValue:forKeyPath: ofObject:change:context: 23
  34. 34. Important! • Notification works by replacing your accessors. • This means that direct ivar access will not produce notifications! 24
  35. 35. Observing with KVO notifications 25
  36. 36. Code! Observing with KVO notifications 25
  37. 37. Derived properties • Example: fullName property that changes when lastName and firstName change • Implement: keyPathsForValuesAffectingValueForKey:, and return a set of all the properties that affect that keyPath. 26
  38. 38. Manual notifications • Example: dynamic value that changes a lot. Calculated value you only want to display at certain times • willChangeValueForKey:, didChangeValueForKey:, automaticallyNotifyObserversForKey: 27
  39. 39. Manual notifications and derived properties 28
  40. 40. Code! Manual notifications and derived properties 28
  41. 41. Careful! • addObserver:… does not throw an exception when you get the keyPath wrong. • If you observe a path with multiple stages, you should observer at every level in the path: • “document.header.title” 29
  42. 42. Observing Array changes • Difficult. You can't observe them at all • (in KVO, only the property is observed, not the value) • Option 1: mutableArrayValueForKey: • Returns a proxy (expensive) that sends notifications when modified • Option 2: Implement all the array- related accessors 30
  43. 43. KVC Accessor selector formats {property} memberOf{property}: set{property}: intersect{property}: insertObject:in{property}AtIndex: _set{property}: insert{property}:atIndexes: {property}ForKeyPath: removeObjectFrom{property}AtIndex: _{property}ForKeyPath: remove{property}AtIndexes: get{property} replaceObjectIn{property}AtIndex:withObject: _get{property} replace{property}AtIndexes:with{property}: is{property} add{property}Object: _is{property} remove{property}: validate{property}:error: remove{property}Object: countOf{property} add{property}: objectIn{property}AtIndex: getPrimitive{property} {property}AtIndexes: primitive{property} get{property}:range: setPrimitive{property}: enumeratorOf{property} 31
  44. 44. Observe array element changes • You can’t. You have to observe each of the elements individually • Solution: NSArrayController • Bind the 'contents' property to the array of interest and observe the path arrangedObjects.{propertyName} • For insertions and deletions, observe the arrangedObjects property directly. 32
  45. 45. Uses for KVO? • Coherence between multiple views and a model • Simplifying flow control • Simplifying undo implementation • Any kind of observer, not only UI views. • Binding controllers: NSController and NSArrayController are based on KVO 33
  46. 46. Bindings 34
  47. 47. What is it? “Allows you to establish a mediated connection between a view and a piece of data, “binding” them such that a change in one is reflected in the other” - Cocoa Bindings Programming Topics guide • Not restricted to 'views' and 'models'. General binding mechanism. 35
  48. 48. Manual binding • Call: bind:toObject:withKeyPath:options: on the ‘view’ object • The ‘view’ will use KVC/KVO • KVC to load the initial values • Receives notifications via KVO • Changes the ‘model’ with KVC 36
  49. 49. Manual bindings 37
  50. 50. Code! Manual bindings 37
  51. 51. Binding Controllers • Basic binding works without controllers! • Object controller: dumb wrapper around KVO • Array Controller: selection proxy for master- detail UI, and observing of arrays. • User Defaults Controller: Simulates KVC/KVO compliance! 38
  52. 52. Bindings in IB 39
  53. 53. Code! Bindings in IB 39
  54. 54. (if time permits) 40
  55. 55. One more thing... Value Transformers (if time permits) 40
  56. 56. Goal: Reduce 'glue' code 41
  57. 57. Goal: Reduce 'glue' code • Example: binding an 'enabled' control to a 'false' property 41
  58. 58. Goal: Reduce 'glue' code • Example: binding an 'enabled' control to a 'false' property • Example: showing an image for a string property 41
  59. 59. Goal: Reduce 'glue' code • Example: binding an 'enabled' control to a 'false' property • Example: showing an image for a string property • Example: handling null values on the model 41
  60. 60. Available value transformers: • NSNegateBooleanTransformer • NSIsNilTransformer • NSIsNotNilTransformer • NSUnarchiveFromDataTransformer • NSKeyedUnarchiveFromDataTransformer • Custom (write your own transformer!) 42
  61. 61. Value Transformers 43
  62. 62. Code! Value Transformers 43
  63. 63. Resources • Introduction to Cocoa Bindings Programming Topics (Apple) • Key Value Coding programming guide (Apple) • Key Value Observing programming guide (Apple) • Model Object Implementation Guide (Apple) • Late Night Cocoa episode 35: KVC/KVO with Stefen Frey • Introduction to Cocoa Bindings by Scott Stevenson • Cocoa Bindings Wiki page at Cocoadev.com 44
  64. 64. 45
  65. 65. The End 45

×