First step was to make the tools inherit from NSResponder:
@interface BWTool : NSResponder { // blah } // ... more blah @end // BWToolThen, in the view class where the tool gets set, put the tool in the responder chain by setting its next responder to be the view's current next responder. If a different tool gets set, take the current tool's next responder and give it to the new tool. Otherwise the view gets its original next responder back:
- (void) setTool: (BWTool *) newTool { NSResponder *nextResponder; // this is the next element in the chain if (currentTool != nil) { nextResponder = [currentTool nextResponder]; } else { nextResponder = [self nextResponder]; } // decide who gets to point to the next responder if (newTool != nil) { // stick the tool into the chain [self setNextResponder: newTool]; [newTool setNextResponder: nextResponder]; } else { // cut the tool out of the chain (if there was one) [self setNextResponder: nextResponder]; } [newTool retain]; [currentTool release]; currentTool = newTool; } // setDrawToolAnd now tools can have action methods, and menu items that enable and disable appropriately.
- (NSString*) title { return (title); } // title - (void) setTitle: (NSString *) newTitle { [title autorelease]; title = [newTitle copy]; } // setTitleFor maximum safety in the face of threads, use this:
- (NSString *) title { return [[title retain] autorelease]; } // titleThis puts
title
into the current thread's autorelease pool, so title
is protected from being destroyed by someone else in another thread.
- (void) setTitle: (NSString *) newTitle { // use a mutex or NSLock to protect this if (title != newtitle) { [title release]; title = [newTitle copy]; } } // setTitleBy making a copy of the object, you're protected from another thread changing the value underneath you.
id
instance variable in your class, and make methods to set and get it:id delegate; ... -(void) setDelegate: (id) del { delegate = del; // you don't need to retain it } // setDelegate - (id) delegate { return (delegate); } // delegate
NSObject
so the compiler won't generate warnings, and also to document the delegate methods you support:@interface NSObject(BWStitchViewDelegate) - (BOOL) shouldHandleStuff: (NSData *) data; @end
... if ([delegate respondsToSelector: @selector(shouldHandleStuff:)]) { BOOL blah; blah = [delegate shouldHandleStuff: somedata]; if (blah) ... }
- (BOOL) respondsToSelector: (SEL) aSelector { NSLog (@"%s", (char *) aSelector); return ([super respondsToSelector: aSelector]); } // respondsToSelectorThis takes advantage of an implementation detail where the
SEL
is actually a pointer to a C string[themStitches sortUsingSelector: @selector(compareByRowLocation:)];And this selector on the BWCrossStitch class:
- (NSComparisonResult) compareByRowLocation: (BWCrossStitch *) thing2;Figure out which is lesser or greater, and return one of these. Note that
self
is the object's logical value, not the actual value of the self
pointer.
NSOrderedAsending
if self
< thing2
NSOrderedDescending
if self
> thing2
NSOrderedSame
if self
== thing2