SEL performSelector和arguments [英] SEL performSelector and arguments
问题描述
当你拥有一个SEL对象时,似乎应该有一种简单的方法来调用带有一些参数的选择器。我似乎无法找到正确的语法。
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 ];
}
推荐答案
看一下< a href =http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html =noreferrer> NSObject
文档。在这种情况下:
Take a look at the NSObject
documentation. In this case:
[parent performSelector:sel withObject:[NSNumber numberWithInt:i]];
(注意此方法实际列在 NSObject
协议文档)。由于 - [NSObject performSelector:withObject:]
需要一个对象参数,你必须在父类的类中写一个包装器,如
(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]];
}
取消装箱 NSNumber
。
如果你真的想调用一个直接接受非对象参数的方法(例如,你没有对被调用者来源的控制而不是想添加一个类别),你可以使用 NSInvocation
:
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];
在旁注中,您的方法看起来像 init
方法,但不遵循Objective-C的正确初始化模式。您需要调用超类初始值设定项,并且需要测试该调用的 nil
结果,并且必须从初始化方法返回self。在所有情况下,您的Objective-C初始化方法应如下所示:
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;
}
您的方法(如果是init方法)将如下所示:
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;
}
为了更加符合Objective-C风格,我会重命名初始值设定项 - (id)initWithSelector:owner:
。
To be more Objective-C stylistically, I would rename the initializer -(id)initWithSelector:owner:
as well.
这篇关于SEL performSelector和arguments的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!