It seems like there should be an easy way to call a selector with some arguments when all you have is a SEL object. I can't seem to find the correct syntax.
-(MyClass*) init: (SEL)sel owner:(NSObject*) parent
{
int i =10;
[parent performSelector:sel:i ];
}
Take a look at the NSObject
documentation. In this case:
[parent performSelector:sel withObject:[NSNumber numberWithInt:i]];
(note this method is actually listed in the NSObject
protocol documentation). Since -[NSObject performSelector:withObject:]
requires an object argument, you will have to write a wrapper in parent's class like
-(void)myMethodForNumber:(NSNumber*)number {
[self myMethod:[number intValue]];
}
to unbox the NSNumber
.
If you really want to invoke a method that takes non-object arguments directly (for example, you don't have control of the callee source and don't want to add a category), you can use NSInvocation
:
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[parent methodSignatureForSelector:sel]];
[inv setSelector:sel];
[inv setTarget:parent];
[inv setArgument:&i atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
[inv invoke];
On a side note, your method looks like an init
method, but does not follow the correct initializer pattern for Objective-C. You need to call the super-classes initializer, and you need to test for a nil
result from that call and you must return self from the initializer method. In all cases, your Objective-C initializer methods should look like:
-(id)myInitMethod {
self = [super init];
if(self != nil) {
//perform initialization of self
}
return self;
}
Your method (if it's an init method) would then look like:
-(id) init: (SEL)sel owner:(NSObject*) parent
{
self = [super init];
if(self != nil) {
int i = 10;
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[parent methodSignatureForSelector:sel]];
[inv setSelector:sel];
[inv setTarget:parent];
[inv setArgument:&i atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
[inv invoke];
}
return self;
}
To be more Objective-C stylistically, I would rename the initializer -(id)initWithSelector:owner:
as well.