Як створити "масив селекторів"


82

Я використовую 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;
}

Відповіді:


79

Чи можете ви зберігати рядки та використовувати NSSelectorFromString?

З документів

NSSelectorFromString

Повертає селектор із заданим іменем.

SEL NSSelectorFromString (
   NSString *aSelectorName
);

2
Невідповідне рішення, коли потрібен лише масив селекторів.
Алекс Н.

1
NSPointerArrayкраще.
DawnSong

43

Це створює об’єкт із селектора:

[NSValue valueWithPointer:@selector(x)]

2
Як би ви взяли витяг селектора з цього для використання performSelector:?
Дін Келлі

3
@DeanKelly відповів тут stackoverflow.com/questions/575055 / ... по махрових franguiadakis
ABCD.ca

1
Потрібен тип акторів, як показано нижче,SEL x = (SEL)selectorValue.pointerValue;
DawnSong

35

Чому б просто не використовувати простий масив C?

static const SEL selectors[] = {@selector(method1),
                                ....
                                @selector(method7)};

...

for (int i = 0; i < sizeof(selectors)/sizeof(selectors[0]); i++) {
  [self performSelector:selectors[i]];
  // ....
}

3
Добре, але staticтут не потрібно (ініціалізатор не є константою часу компіляції).
Алекс Н.

12

Ви також можете створити масив 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 занадто дорогий.
DawnSong

1

Якщо список статичний, я б вирішив рішення 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метод до класу і реалізувати там виклик методу.


1

Я хотів би доповнити два методи зберігання селекторів у масиві,

По-перше, NSPointerArrayможна зберігати непрозорий вказівник, наприклад SEL, як сказав доктор Apple ,

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

По-друге, масив у стилі С набагато простіший,

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

Вибирайте будь-який, як хочете.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.