Re: How does Cocoa implement delegate/callback?
Re: How does Cocoa implement delegate/callback?
- Subject: Re: How does Cocoa implement delegate/callback?
- From: Jérôme Laurens <email@hidden>
- Date: Fri, 15 Nov 2002 16:26:11 +0100
Le jeudi, 14 nov 2002, ` 18:41 Europe/Zurich, Bill Cheeseman a icrit :
>
There are many Cocoa methods and functions, like NSBeginAlertSheet,
>
that
>
give the user an option to pass a temporary delegate and a callback
>
selector. How does Cocoa implement this?
>
>
I ask because I would like to provide a similar option to clients of a
>
class
>
I'm writing. A complicating factor is that the class I'm writing
>
covers a C
>
API that expects the callback to be a C function. I want my clients to
>
be
>
able to write their callbacks as Objective-C methods.
>
>
I suppose I can implement the C callback as a function in the class I'm
>
writing and register it with the C API. Then, when my C callback
>
function is
>
triggered by the C API, I can have it send a message to my client's
>
callback
>
selector. But how? Telling the delegate to
>
performSelector:withObject:withObject: won't work because the callback
>
method I specify has too many parameters. And I can't figure out how
>
to get
>
NSInvocation to work.
>
>
Is this the best approach? If so, I'll keep digging.
>
>
I don't guarantee that the following code works as is, but the idea is
there (it is a slight modification of something I use myself)
[myController doSomethingOnObject: myObject repeat: 10 delegate:
myObjectDelegate didEndSelector: selector];
where selector is one of
@selector(myControllerDidSomething:)
@selector(controller:repeatedSomethingOnObject:)
@selector(myController:didSomethingOnObject:repeated:)
@selector(myController:didSomethingOnObject:number:userInfo:)
@implementation MyObjectDelegate
- (void) myControllerDidSomething: (id) aController{}
- (void) controller: (id) aController repeatedSomethingOnObject: (id)
anObject{}
- (void) myController: (id) aController didSomethingOnObject: (id)
anObject repeated: (int) times{}
- (void) myController: (id) aController didSomethingOnObject: (id)
anObject number: (int) times userInfo: (id) userInfo{}
@end
@implementation MyController
- (void) doSomethingOnObject: (id) object repeat: (int) times delegate:
(id) aDelegate didEndSelector: (Sel) aSelector userInfo: (id) userInfo
{
// really do what you have to do
NSInvocation * invocation = nil;
if((aSelector == NULL) || ![aDelegate respondsToSelector:
aSelector]) goto theBeach;
NSMethodSignature * MS = [aDelegate methodSignatureForSelector:
aSelector];
int numberOfArguments = [MS numberOfArguments];
//standard stuff
invocation = [NSInvocation invocationWithMethodSignature: MS];
[invocation setSelector: aSelector];
[invocation setTarget: aDelegate];
if(numberOfArguments>2)
{
// second argument "aController" is an object
char * type;
type = [MS getArgumentTypeAtIndex: 2];
if(strcmp(@encode(id), type)) goto hell;
[invocation setArgument: &self atIndex: 2];
}
if(numberOfArguments>3)
{
// third argument "anObject" is an object
char * type;
type = [MS getArgumentTypeAtIndex: 3];
if(strcmp(@encode(id), type)) goto hell;
[invocation setArgument: (object? &object: nil) atIndex: 3];
}
if(numberOfArguments>4)
{
// fourth argument "times" is an int
char * type;
type = [MS getArgumentTypeAtIndex: 4];
if(strcmp(@encode(int), type)) goto hell;
[invocation setArgument: × atIndex: 4];
}
if(numberOfArguments>5)
{
// fifth argument "times" is an int
char * type;
type = [MS getArgumentTypeAtIndex: 5];
if(strcmp(@encode(id), type)) goto hell;
[invocation setArgument: (userInfo? & userInfo: nil) atIndex:
5];
}
theBeach:
[invocation invoke];
hell:
// unexpected format...
return;
}
@end
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.