【问题标题】:How to create an "array of selectors"如何创建“选择器数组”
【发布时间】:2011-01-14 15:41:00
【问题描述】:

我正在使用 iPhone SDK (3.0),我正在尝试创建一个选择器数组来调用一个类中的各种方法。

显然,我做错了(我认为@selector 不被视为一个类,因此将它们填充到 NSArray 中是行不通的)。

我试过这个,但显然是错误的。

有没有一种简单的方法来拥有这样的选择器数组?或者有没有更好的方法来遍历一组方法?

selectors = [NSArray arrayWithObjects:
                          @selector(method1),
                          @selector(method2),
                          @selector(method3),
                          @selector(method4),
                          @selector(method5),
                          @selector(method6),
                          @selector(method7), nil];

for (int i = 0; i < [selectors count]; i++) {
    if ([self performSelector:[selectors objectAtIndex:i]]) // do stuff;
}

【问题讨论】:

    标签: ios objective-c nsarray selector


    【解决方案1】:

    你能存储字符串并使用 NSSelectorFromString 吗?

    来自docs

    NSSelectorFromString
    

    返回具有给定名称的选择器。

    SEL NSSelectorFromString (
       NSString *aSelectorName
    );
    

    【讨论】:

    • 当只需要一组选择器时,这不是一个合适的解决方案。
    • NSPointerArray 更好。
    【解决方案2】:

    这会从选择器中创建一个对象:

    [NSValue valueWithPointer:@selector(x)]
    

    【讨论】:

    • 你将如何从中提取选择器以供performSelector:使用?
    • @DeanKelly 在这里回答 stackoverflow.com/questions/575055/… 特里·弗兰吉亚达基斯
    • 需要类型转换,如下,SEL x = (SEL)selectorValue.pointerValue;
    【解决方案3】:

    为什么不只使用一个简单的 C 数组?

    static const SEL selectors[] = {@selector(method1),
                                    ....
                                    @selector(method7)};
    
    ...
    
    for (int i = 0; i < sizeof(selectors)/sizeof(selectors[0]); i++) {
      [self performSelector:selectors[i]];
      // ....
    }
    

    【讨论】:

    • 很好,但是这里不需要static(初始化器不是编译时常量)。
    【解决方案4】:

    您还可以创建NSInvocations 的数组。如果您需要与选择器一起使用的参数,这很方便。

    NSMethodSignature *sig = [[yourTarget class] instanceMethodSignatureForSelector:yourSEL];
    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig];
    [inv setTarget:yourTarget];
    [inv setSelector:yourSEL];
    [inv setArgument:&yourObject atIndex:2]; // Address of your object
    

    【讨论】:

    • NSInvocation 太贵了。
    【解决方案5】:

    如果列表是静态的,我会使用 KennyTM 的解决方案,但如果您需要动态数组或集合,除了存储选择器字符串之外,另一个选项是创建一个具有 SEL 属性或 ivar 的对象,并存储它。

    @interface SelectorObject : NSObject
    @property (assign, readonly, nonatomic) SEL selector;
    - (id)initWithSelector:(SEL)selector;
    @end
    
    @implementation SelectorObject
    - (id)initWithSelector:(SEL)selector {
      self = [super init];
      if (self) {
        _selector = selector;
      }
      return self;
    }
    @end
    

    然后您也可以向该类添加一个perform 方法,并在那里实现方法调用。

    【讨论】:

      【解决方案6】:

      我想补充两种将选择器存储在数组中的方法,

      首先NSPointerArray可以存储不透明指针,比如SEL,正如Apple doc所说,

      NSPointerArray *selectors = [[NSPointerArray alloc] initWithOptions: NSPointerFunctionsOpaqueMemory];
      [selectors addPointer:@selector(onSendButton:)];
      [button addTarget: self action:[selectors pointerAt:0] forControlEvents:UIControlEventTouchUpInside];
      

      第二,C风格的数组要简单得多,

      SEL selectors[] = { @selector(onSendButton:) };
      [button addTarget: self action:selectors[0] forControlEvents:UIControlEventTouchUpInside];
      

      任意选择。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-22
        • 2013-07-22
        • 2014-12-07
        • 2021-08-22
        • 2017-11-13
        • 1970-01-01
        • 2013-03-17
        • 1970-01-01
        相关资源
        最近更新 更多