Re: NSDocument Enabling and handling menu items without implementing the action method in the document class
Re: NSDocument Enabling and handling menu items without implementing the action method in the document class
- Subject: Re: NSDocument Enabling and handling menu items without implementing the action method in the document class
- From: Graham Cox <email@hidden>
- Date: Sun, 19 Jul 2009 22:46:38 +1000
On 19/07/2009, at 10:06 PM, Eyal Redler wrote:
This works fine but it requires me to write an annoying amount such
glue code every time I add an action so I'm looking for a better way
to do this. Is it possible to further delegate the action methods
and menu validation from the NSDocument subclass? The best way for
me would be to have internalObject implement validateMenuItem and
myAction and have the NSDocument pass them along without actually
implementing each action method.
It sure is - use invocation forwarding. You need to override the
following NSObject methods:
- (NSMethodSignature *) methodSignatureForSelector:(SEL) aSelector;
- (BOOL) respondsToSelector:(SEL) aSelector;
- (void) forwardInvocation:(NSInvocation*) invocation;
The first two methods should query the object you're devolving to when
super returns nil and NO respectively, and the third should invoke the
invocation on the new target. The result is that the target object can
act as if it were directly being targeted by the original command
(action) and even implement its own validateMenuItem: etc.
More on this here: http://www.cocoadev.com/index.pl?NSInvocation
It's hard to find in the Apple documentation so I was unable to
immediately find the right page there, but it's in there somewhere.
For example, I have a target object referred to as "active layer" and
this code exists in my view's controller:
- (void) forwardInvocation:(NSInvocation*) invocation
{
SEL aSelector = [invocation selector];
if ([[self activeLayer] respondsToSelector:aSelector])
[invocation invokeWithTarget:[self activeLayer]];
else
[self doesNotRecognizeSelector:aSelector];
}
- (NSMethodSignature *) methodSignatureForSelector:(SEL) aSelector
{
NSMethodSignature* sig;
sig = [super methodSignatureForSelector:aSelector];
if ( sig == nil )
sig = [[self activeLayer] methodSignatureForSelector:aSelector];
return sig;
}
- (BOOL) respondsToSelector:(SEL) aSelector
{
return [super respondsToSelector:aSelector] || [[self activeLayer]
respondsToSelector:aSelector];
}
hope this helps,
--Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden