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

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

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

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

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

Edit:

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

Edit2:

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

Ответы [ 3 ]

3 голосов
/ 19 декабря 2011

Вы можете использовать тип 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.

2 голосов
/ 19 декабря 2011

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

1 голос
/ 19 декабря 2011

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

NSString *selectors[] = { ... } 

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

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

@property(nonatomic, assign) NSString **selectors;
...