2008-11-18 4 views
53

у меня есть пример кода, который получает SEL от текущего объекта,Создание селектора из имени метода с параметрами

SEL callback = @selector(mymethod:parameter2); 

И у меня есть метод, как

-(void)mymethod:(id)v1 parameter2;(NSString*)v2 { 
} 

Теперь мне нужно переместите mymethod на другой объект, скажем myDelegate.

Я попытался:

SEL callback = @selector(myDelegate, mymethod:parameter2); 

, но это не будет компилироваться.

+2

@Jim Puls - это на самом деле проблема с Objective-C ... это не более специфично для какао или какао-touch, чем для iphone-sdk. Кроме того, мы собираемся с тегом object-c поверх objectivec в эти дни :) – 2008-11-18 02:57:28

ответ

95

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 секунд.

16

Вы не можете передать параметр в @selector().

Похоже, вы пытаетесь реализовать обратный вызов. Лучший способ сделать это было бы что-то вроде этого:

[object setCallbackObject:self withSelector:@selector(myMethod:)]; 

Тогда в setCallbackObject вашего объекта: withSelector: метод: вы можете назвать ваш метод обратного вызова.

-(void)setCallbackObject:(id)anObject withSelector:(SEL)selector { 
    [anObject performSelector:selector]; 
} 
+0

Это тоже не чисто iPhone. Вы можете прочитать документ Apple «Язык программирования Obective-C 2.0», который можно найти здесь http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/chapter_1_section_1.html – 2008-11-18 02:43:10

+4

Чтобы вызвать селектор, вы необходимо позвонить: [anObject performSelector: selector]; – 2009-07-23 19:42:20

5

Помимо того, что уже было сказано о селекторах, вы можете посмотреть класс NSInvocation.

NSInvocation - это сообщение Objective-C, представляемое как статическое, то есть это действие, превращенное в объект. Объекты NSInvocation используются для хранения и пересылки сообщений между объектами и между приложениями, в основном объектами NSTimer и системой распределенных объектов.

Объект NSInvocation содержит все элементы сообщения Objective-C: цель, селектор, аргументы и возвращаемое значение. Каждый из этих элементов может быть установлен непосредственно, а возвращаемое значение устанавливается автоматически при отправке объекта NSInvocation.

Имейте в виду, что, хотя это полезно в определенных ситуациях, вы не используете NSInvocation в обычный день кодирования.Если вы просто пытаетесь заставить два объекта разговаривать друг с другом, подумайте над определением неофициального или формального протокола делегатов или передайте селектор и целевой объект, как уже упоминалось.

Смежные вопросы