Your SlideShare is downloading. ×
Easy undo.key
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Easy undo.key

708

Published on

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

  • Be the first to like this

No Downloads
Views
Total Views
708
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide












































































































































































  • Transcript

    • 1. A How-To for an Easy Undo
    • 2. Last Time • Objective C • Tutorial resources • XCode projects
    • 3. This Time • A simple, common pattern with Cocoa
    • 4. Undo/Redo • You should have undo in your app.
    • 5. The Theory of Undo @interface dot : NSObject { int x; int y; }
    • 6. The Theory of Undo History of X @interface dot : NSObject { • x = 100; int x; int y; }
    • 7. The Theory of Undo History of X @interface dot : NSObject { • x = 100; int x; int y; • x = 22; }
    • 8. The Theory of Undo History of X @interface dot : NSObject { • x = 100; int x; int y; • x = 22; } •x=
    • 9. The Theory of Undo History of X @interface dot : NSObject { int x; x = 22; • int y; } • x = 100; •x=
    • 10. The Theory of Undo History of X x = 22; x = 100; •x=
    • 11. The Theory of Undo Undo Stack x = 22; x = 100; •x=
    • 12. The Theory of Undo Undo Stack x = 22; •x= x = 100;
    • 13. The Theory of Undo Undo Stack x = 22; •x= x = 100;
    • 14. The Theory of Undo Undo Stack x = 22; x= x = 100;
    • 15. The Theory of Undo Undo Stack x = 22; x= x = 100;
    • 16. The Theory of Undo Undo Stack Redo Stack x = 22; x= x = 100;
    • 17. Undo Stack Redo Stack x = 22; x= x = 100;
    • 18. Undo Stack Redo Stack
    • 19. NSUndoManager Undo Stack Redo Stack
    • 20. NSUndoManager
    • 21. NSUndoManager
    • 22. NSUndoManager Q: How many managers?
    • 23. NSUndoManager Q: How many managers? A1: It depends.
    • 24. NSUndoManager Q: How many managers? A1: It depends... A2: ...but often one per doc.
    • 25. NSUndoManager Q: How many managers? A1: It depends... A2: ...but often one per doc. NSDocument
    • 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. Registering Undos 1. Simple Undo 2. Invocation-based Undo
    • 28. Simple Undo [self.document.undoManager registerUndoWithTarget: target selector: aSelector object: anObject];
    • 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. 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. 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. 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. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>];
    • 34. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; Magic
    • 35. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation Magic
    • 36. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation Magic
    • 37. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation Magic
    • 38. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation • “An action turned into an object.”
    • 39. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation • “An action turned into an object.” • Contains: target, selector, arguments, etc.
    • 40. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation • “An action turned into an object.” • Contains: target, selector, arguments, etc.
    • 41. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; NSInvocation • “An action turned into an object.” • Contains: target, selector, arguments, etc. byte level
    • 42. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; What happens:
    • 43. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; What happens: • Prepare target - “incoming!”
    • 44. Invocation-based Undo [[undoManager prepareWithInvocationTarget: target] <any method>]; What happens: • Prepare target - “incoming!” • becomes an NSInvocation <any method> object
    • 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. 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. 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. Invocation Undo: Example - (void) setX: (int) newX { NSUndoManager undoManager = self.document.undoManager; if (oldX != newX) { [[undoManager prepareWithInvocationTarget:self] setX:oldX]; [myObject setX:newX]; } }
    • 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. Undo Details
    • 51. Undo Details 1. [undoManager setActionName:@”What’s Changing”];
    • 52. Undo Details 1. [undoManager setActionName:@”What’s Changing”]; 2. Memory management: what’s going on?
    • 53. Undo Details 1. [undoManager setActionName:@”What’s Changing”]; 2. Memory management: what’s going on? • Simple - retains object, not target
    • 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. 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. Undo Architecture • How do we make sure all changes are captured? • Parallel controller objects? • ...that gets repetitive...
    • 57. Ta da!
    • 58. Key/Value Observation (K
    • 59. Key/Value * Observation (K (the basics)
    • 60. K VO: What is it? • Built into base NSObject
    • 61. K VO: What is it? • Built into base NSObject • Automated notifications of property changes
    • 62. K VO: What is it? • Built into base NSObject • Automated notifications of property changes... • ...but allows for manual override
    • 63. K VO: What’s a key? • A string that identifies a property
    • 64. K VO: What’s a key? • A string that identifies a property • e.g. via an accessor method or instance variable
    • 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. 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. K VO: How to use it. 1. Must be KVO compliant for properties you want to observe
    • 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. 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. 1. K VO Compliance Depends on what kind of property. • To-one • To-many (indexed) • To-many (unordered)
    • 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. 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. 2. K VO Registration [object addObserver: (NSObject *) anObserver forKeyPath: (NSString *) keyPath options: (NSKeyValueObservingOptions) options context: (void *) context];
    • 74. 3. K VO Notifications - (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) object change: (NSDictionary *) change context: (void *) context
    • 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. Put it all together...

    ×