Easy undo.key

897 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
897
On SlideShare
0
From Embeds
0
Number of Embeds
64
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide












































































































































































  • Easy undo.key

    1. 1. A How-To for an Easy Undo
    2. 2. Last Time • Objective C • Tutorial resources • XCode projects
    3. 3. This Time • A simple, common pattern with Cocoa
    4. 4. Undo/Redo • You should have undo in your app.
    5. 5. The Theory of Undo @interface dot : NSObject { int x; int y; }
    6. 6. The Theory of Undo History of X @interface dot : NSObject { • x = 100; int x; int y; }
    7. 7. The Theory of Undo History of X @interface dot : NSObject { • x = 100; int x; int y; • x = 22; }
    8. 8. The Theory of Undo History of X @interface dot : NSObject { • x = 100; int x; int y; • x = 22; } •x=
    9. 9. The Theory of Undo History of X @interface dot : NSObject { int x; x = 22; • int y; } • x = 100; •x=
    10. 10. The Theory of Undo History of X x = 22; x = 100; •x=
    11. 11. The Theory of Undo Undo Stack x = 22; x = 100; •x=
    12. 12. The Theory of Undo Undo Stack x = 22; •x= x = 100;
    13. 13. The Theory of Undo Undo Stack x = 22; •x= x = 100;
    14. 14. The Theory of Undo Undo Stack x = 22; x= x = 100;
    15. 15. The Theory of Undo Undo Stack x = 22; x= x = 100;
    16. 16. The Theory of Undo Undo Stack Redo Stack x = 22; x= x = 100;
    17. 17. Undo Stack Redo Stack x = 22; x= x = 100;
    18. 18. Undo Stack Redo Stack
    19. 19. NSUndoManager Undo Stack Redo Stack
    20. 20. NSUndoManager
    21. 21. NSUndoManager
    22. 22. NSUndoManager Q: How many managers?
    23. 23. NSUndoManager Q: How many managers? A1: It depends.
    24. 24. NSUndoManager Q: How many managers? A1: It depends... A2: ...but often one per doc.
    25. 25. NSUndoManager Q: How many managers? A1: It depends... A2: ...but often one per doc. NSDocument
    26. 26. NSUndoManager Q: How many managers? A1: It depends... A2: ...but often one per doc. NSDocument eebie # 472: Co coa fr saved arked as un doc m not empty if undo stack
    27. 27. Registering Undos 1. Simple Undo 2. Invocation-based Undo
    28. 28. Simple Undo [self.document.undoManager registerUndoWithTarget: target selector: aSelector object: anObject];
    29. 29. Simple Undo: Example - (void) setX: (int) newX { NSUndoManager undoManager = self.document.undoManager; if (x != newX) { [undoManager registerUndoWithTarget: self selector: @selector(setX:) object: x]; [myObject setX:newX]; } }
    30. 30. Simple Undo: Example - (void) setX: (int) newX { NSUndoManager undoManager = self.document.undoManager; if (x != newX) { [undoManager registerUndoWithTarget: self selector: @selector(setX:) object: x]; ject [myObject setX:newX]; } } N ot a n ob
    31. 31. Simple Undo: Example - (void) setX: (NSNumber *) newX { NSUndoManager undoManager = self.document.undoManager; if (![x isEqual:newX]) { [undoManager registerUndoWithTarget: self selector: @selector(setX:) object: x]; [myObject setX:newX]; } }
    32. 32. Simple Undo: Example - (void) setX: (NSNumber *) newX { NSUndoManager undoManager = self.document.undoManager; if (![x isEqual:newX]) { [undoManager registerUndoWithTarget: self selector: @selector(setX:) object: x]; [myObject setX:newX]; } } Tip: Cocoa uses objects. You usually should too.
    33. 33. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>];
    34. 34. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; Magic
    35. 35. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation Magic
    36. 36. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation Magic
    37. 37. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation Magic
    38. 38. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation • “An action turned into an object.”
    39. 39. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation • “An action turned into an object.” • Contains: target, selector, arguments, etc.
    40. 40. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation • “An action turned into an object.” • Contains: target, selector, arguments, etc.
    41. 41. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation • “An action turned into an object.” • Contains: target, selector, arguments, etc. byte level
    42. 42. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; What happens:
    43. 43. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; What happens: • Prepare target - “incoming!”
    44. 44. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; What happens: • Prepare target - “incoming!” • becomes an NSInvocation <any method> object
    45. 45. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; What happens: • Prepare target - “incoming!” • becomes an NSInvocation <any method> object • NSUndoManager doesn’t respond to method> <any
    46. 46. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; What happens: • Prepare target - “incoming!” • becomes an NSInvocation <any method> object • NSUndoManager doesn’t respond to method> <any
    47. 47. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; What happens: • Prepare target - “incoming!” • becomes an NSInvocation <any method> object • NSUndoManager doesn’t respond to method> <any • calls with the NSInvocation forwardInvocation:
    48. 48. Invocation Undo: Example - (void) setX: (int) newX { NSUndoManager undoManager = self.document.undoManager; if (oldX != newX) { [[undoManager prepareWithInvocationTarget:self] setX:oldX]; [myObject setX:newX]; } }
    49. 49. Invocation Undo: Example - (void) setX: (int) newX { NSUndoManager undoManager = self.document.undoManager; if (oldX != newX) { [[undoManager prepareWithInvocationTarget:self] setX:oldX]; [myObject setX:newX]; } } OK
    50. 50. Undo Details
    51. 51. Undo Details 1. [undoManager setActionName:@”What’s Changing”];
    52. 52. Undo Details 1. [undoManager setActionName:@”What’s Changing”]; 2. Memory management: what’s going on?
    53. 53. Undo Details 1. [undoManager setActionName:@”What’s Changing”]; 2. Memory management: what’s going on? • Simple - retains object, not target
    54. 54. Undo Details 1. [undoManager setActionName:@”What’s Changing”]; 2. Memory management: what’s going on? • Simple - retains object, not target • Invocation - Probably retained?
    55. 55. Undo Details 1. [undoManager setActionName:@”What’s Changing”]; 2. Memory management: what’s going on? • Simple - retains object, not target • Invocation - Probably retained? 3. Undo groupings
    56. 56. Undo Architecture • How do we make sure all changes are captured? • Parallel controller objects? • ...that gets repetitive...
    57. 57. Ta da!
    58. 58. Key/Value Observation (K
    59. 59. Key/Value * Observation (K (the basics)
    60. 60. K VO: What is it? • Built into base NSObject
    61. 61. K VO: What is it? • Built into base NSObject • Automated notifications of property changes
    62. 62. K VO: What is it? • Built into base NSObject • Automated notifications of property changes... • ...but allows for manual override
    63. 63. K VO: What’s a key? • A string that identifies a property
    64. 64. K VO: What’s a key? • A string that identifies a property • e.g. via an accessor method or instance variable
    65. 65. K VO: What’s a key? • A string that identifies a property • e.g. via an accessor method or instance variable These accessors... - (void) setHeight: (NSNumber *) newHeight; - (NSNumber *) height;
    66. 66. K VO: What’s a key? • A string that identifies a property • e.g. via an accessor method or instance variable These accessors... ...correspond to this key. - (void) setHeight: (NSNumber *) newHeight; @"height" - (NSNumber *) height;
    67. 67. K VO: How to use it. 1. Must be KVO compliant for properties you want to observe
    68. 68. K VO: How to use it. 1. Must be KVO compliant for properties you want to observe 2. Must register for each property
    69. 69. K VO: How to use it. 1. Must be KVO compliant for properties you want to observe 2. Must register for each property 3. Observer must handle the notification
    70. 70. 1. K VO Compliance Depends on what kind of property. • To-one • To-many (indexed) • To-many (unordered)
    71. 71. 1. K VO Compliance Depends on what kind of property: e.g. - (void • To-one ) setHe - (NSNu ight: ( mber *) NSNumbe height; r *) ne wHeight ; • To-many (indexed) • To-many (unordered)
    72. 72. 1. K VO Compliance Depends on what kind of property: e.g. - (void • To-one ) setHe - (NSNu ight: ( mber *) NSNumbe height; r *) ne wHeight ; • To-many (indexed) • To-many (unordered) - (NSUI e.g. - (NSEn - (id) nteger) umerato countOf r *) en MySet; memberO umerato fMySet: rOfMySe (id) an t; Object;
    73. 73. 2. K VO Registration [object addObserver: (NSObject *) anObserver forKeyPath: (NSString *) keyPath options: (NSKeyValueObservingOptions) options context: (void *) context];
    74. 74. 3. K VO Notifications - (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) object change: (NSDictionary *) change context: (void *) context
    75. 75. 3. K VO Notifications - (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) object change: (NSDictionary *) change context: (void *) context { int kindOfChange = [[change objectForKey:NSKeyValueChangeKindKey] intValue]; id oldValue = [change objectForKey:NSKeyValueChangeOldKey]; id newValue = [change objectForKey:NSKeyValueChangeNewKey]; NSIndexSet *indexSet = [change objectForKey:NSKeyValueChangeIndexesKey]; ...
    76. 76. Put it all together...

    ×