Реализация таблицы диспетчеризации в Objective-C: как объявить массив селекторов

Я пытаюсь реализовать таблицу диспетчеризации, чтобы я мог вызвать селектор с помощью следующего примера кода:

NSInteger i = 2;
[myObject performSelector:selectors[i]];

Я пытаюсь сохранить пользовательские настройки, которые влияют на то, какой метод API вызывается. Прямо сейчас я использую строковое имя селектора и использую NSSelectorFromString, но это немного грязно. Если я использую таблицу диспетчеризации, тогда я могу хранить перечисление.

Как я могу сделать массив селекторов или таблицу диспетчеризации в Objective-C?

Редактировать:

Компилятор жалуется, когда я пытаюсь установить массив селекторов как свойство. @property SEL[] не скомпилируется.

Edit2:

Я использую свою библиотеку API KosherCocoa и хочу вызвать один метод за раз, основываясь на сохраненной пользовательской настройке. Я сохраняю и читаю из файла Plist.

3 ответа

Решение

Вы можете использовать SEL Тип для удержания селекторов. Просто:

SEL dispatchTable[3] = { @selector(doThis:), 
                         @selector(doThat:), 
                         @selector(doTheOther:) 
                       };

Для редактирования используйте NSArray/NSDictionary/ etc селекторов в качестве вашей собственности. Вы не можете использовать массивы C в качестве свойств в Objective C; они не являются одним из поддерживаемых типов (которые являются объектами ObjC, типами CF и базовыми типами C 'Plain Old Data'.)

Хорошо, в наших комментариях ниже, вы должны обернуть селектор в NSValue чтобы позволить вам использовать его в контейнере objc (потому что SEL тип указателя C):

NSMutableArray * dispatchTable2 = [[NSMutableArray alloc] initWithCapacity:3];
SEL selIn = @selector(doThis:);

// Wrap the selector in an NSValue instance
[dispatchTable2 addObject:[NSValue valueWithPointer:selIn]];

// On extracting:
NSValue * valOut = [dispatchTable2 objectAtIndex:0];
SEL selOut = [[dispatchTable2 objectAtIndex:0] pointerValue];
[anObject performSelector:selOut];

Итак, теперь ваша таблица является контейнером objc, хранящимся как свойство или ivar, и вы используете NSValue обернуть SEL указатели с valueWithPointer: и получить SEL с pointerValue,

Я бы рекомендовал использовать NSInvocation вместо селекторов. Они гораздо более гибкие, так как вы можете отправлять один и тот же вызов многим объектам, и вы можете изменять его свойства по мере продвижения.

Один из способов сделать это - использовать массив NSStringsзатем преобразуйте их в SEL во время выполнения, если это повышает удобочитаемость для вас..

NSString *selectors[] = { ... } 

[myObject performSelector:NSSelectorFromString(selectors[i])];

Чтобы использовать это как свойство, используйте

@property(nonatomic, assign) NSString **selectors;
Другие вопросы по тегам