Как я могу динамически создавать селектор во время выполнения с помощью Objective-C?
-
02-07-2019 - |
Вопрос
Я знаю, как создать SEL
во время компиляции с использованием @selector(MyMethodName:)
но я хочу динамически создать селектор из NSString
.Возможно ли это вообще?
Что я могу сделать:
SEL selector = @selector(doWork:);
[myobj respondsToSelector:selector];
Что я хочу сделать:(псевдокод, это явно не работает)
SEL selector = selectorFromString(@"doWork");
[myobj respondsToSelector:selector];
Я искал документацию Apple API, но не нашел способа, который не полагается на время компиляции. @selector(myTarget:)
синтаксис.
Решение
Я не программист Objective-C, просто сочувствую, но, возможно, НССелекторфромстринг это то, что вам нужно.Об этом упоминается в Справочник по времени выполнения что вы можете использовать его для преобразования строки в селектор.
Другие советы
Согласно документации XCode, ваш псевдокод в основном все делает правильно.
Наиболее эффективно присваивать значения переменным SEL во время компиляции с помощью директивы @selector().Однако в некоторых случаях программе может потребоваться преобразовать строку символов в селектор во время выполнения.Это можно сделать с помощью функции NSSelectorFromString:
setWidthHeight = NSSelectorFromString(aBuffer);
Редактировать:Облом, слишком медленно.:П
Я должен был бы сказать это это немного сложнее чем можно предположить из ответов предыдущих респондентов...если ты действительно действительно этого хочешь создать селектор...а не просто «позвонить тому», который у вас «завалялся»…
Вам нужно создать указатель на функцию, которая будет вызываться вашим «новым» методом.поэтому для такого метода, как [self theMethod:(id)methodArg];
, ты бы написал...
void (^impBlock)(id,id) = ^(id _self, id methodArg) {
[_self doSomethingWith:methodArg];
};
а затем вам нужно сгенерировать IMP
блокировать динамически, на этот раз, проходя "сам", SEL
, и любые аргументы...
void(*impFunct)(id, SEL, id) = (void*) imp_implementationWithBlock(impBlock);
и добавьте его в свой класс вместе с точной сигнатурой метода для всей присоски (в данном случае "v@:@"
, возврат void, вызывающий объект, аргумент объекта)
class_addMethod(self.class, @selector(theMethod:), (IMP)impFunct, "v@:@");
Вы можете увидеть несколько хороших примеров такого рода махинации во время выполнения, в одном из моих репозиториев здесь.
Я знаю, что на этот вопрос уже давно был дан ответ, но все же я хочу поделиться.Это можно сделать с помощью sel_registerName
слишком.
Пример кода в вопросе можно переписать следующим образом:
SEL selector = sel_registerName("doWork:");
[myobj respondsToSelector:selector];