Создание селектора из имени метода с параметрами
У меня есть образец кода, который получает SEL
от текущего объекта,
SEL callback = @selector(mymethod:parameter2);
И у меня есть метод вроде
-(void)mymethod:(id)v1 parameter2;(NSString*)v2 {
}
Теперь мне нужно переместить mymethod
на другой объект, скажем myDelegate
.
Я пробовал:
SEL callback = @selector(myDelegate, mymethod:parameter2);
но он не будет компилироваться.
Ответы
Ответ 1
SEL - тип, представляющий селектор в Objective-C. Ключевое слово @selector() возвращает SEL, который вы описываете. Это не указатель на функцию, и вы не можете передавать ему какие-либо объекты или ссылки любого типа. Для каждой переменной в селекторе (методе) вы должны представить это в вызове @selector. Например:
-(void)methodWithNoParameters;
SEL noParameterSelector = @selector(methodWithNoParameters);
-(void)methodWithOneParameter:(id)parameter;
SEL oneParameterSelector = @selector(methodWithOneParameter:); // notice the colon here
-(void)methodWIthTwoParameters:(id)parameterOne and:(id)parameterTwo;
SEL twoParameterSelector = @selector(methodWithTwoParameters:and:); // notice the parameter names are omitted
Селекторы обычно передаются методам делегирования и обратным вызовам, чтобы указать, какой метод следует вызывать на конкретном объекте во время обратного вызова. Например, при создании таймера метод обратного вызова определен как:
-(void)someMethod:(NSTimer*)timer;
Поэтому, когда вы планируете таймер, вы должны использовать @selector, чтобы указать, какой метод на вашем объекте будет отвечать за обратный вызов:
@implementation MyObject
-(void)myTimerCallback:(NSTimer*)timer
{
// do some computations
if( timerShouldEnd ) {
[timer invalidate];
}
}
@end
// ...
int main(int argc, const char **argv)
{
// do setup stuff
MyObject* obj = [[MyObject alloc] init];
SEL mySelector = @selector(myTimerCallback:);
[NSTimer scheduledTimerWithTimeInterval:30.0 target:obj selector:mySelector userInfo:nil repeats:YES];
// do some tear-down
return 0;
}
В этом случае вы указываете, что объект obj должен быть отправлен с myTimerCallback каждые 30 секунд.
Ответ 2
Вы не можете передать параметр в @selector().
Похоже, вы пытаетесь реализовать обратный вызов. Лучший способ сделать это будет примерно так:
[object setCallbackObject:self withSelector:@selector(myMethod:)];
Затем в вашем объекте setCallbackObject: withSelector: method: вы можете вызвать свой метод обратного вызова.
-(void)setCallbackObject:(id)anObject withSelector:(SEL)selector {
[anObject performSelector:selector];
}
Ответ 3
Помимо того, что уже было сказано о селекторах, вы можете посмотреть класс NSInvocation.
NSInvocation - это сообщение Objective-C, отображаемое как статическое, то есть это действие, превращенное в объект. Объекты NSInvocation используются для хранения и пересылки сообщений между объектами и между приложениями, в основном объектами NSTimer и системой распределенных объектов.
Объект NSInvocation содержит все элементы сообщения Objective-C: цель, селектор, аргументы и возвращаемое значение. Каждый из этих элементов может быть установлен непосредственно, а возвращаемое значение устанавливается автоматически при отправке объекта NSInvocation.
Имейте в виду, что, хотя это полезно в определенных ситуациях, вы не используете NSInvocation в обычный день кодирования. Если вы просто пытаетесь заставить два объекта разговаривать друг с другом, подумайте над определением неофициального или формального протокола делегатов или передайте селектор и целевой объект, как уже упоминалось.