SEL performSelector和arguments [英] SEL performSelector and arguments

查看:79
本文介绍了SEL performSelector和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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆