Реализация таблицы диспетчеризации в 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;