it-swarm.com.de

Erstellen eines Selektors aus einem Methodennamen mit Parametern

Ich habe ein Codebeispiel, das ein SEL vom aktuellen Objekt erhält.

SEL callback = @selector(mymethod:parameter2);

Und ich habe eine Methode wie

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

Jetzt muss ich mymethod zu einem anderen Objekt verschieben, sagen wir myDelegate.

Ich habe versucht:

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

aber es wird nicht kompiliert.

57
BlueDolphin

SEL ist ein Typ, der einen Selektor in Objective-C darstellt. Das Schlüsselwort @selector () gibt ein von Ihnen beschriebenes SEL zurück. Es ist kein Funktionszeiger und Sie können ihm keine Objekte oder Referenzen übergeben. Für jede Variable im Selektor (Methode) müssen Sie diese im Aufruf von @selector darstellen. Beispielsweise:

-(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

Selektoren werden im Allgemeinen übergeben, um Methoden und Rückrufe zu delegieren, um anzugeben, welche Methode für ein bestimmtes Objekt während eines Rückrufs aufgerufen werden soll. Wenn Sie beispielsweise einen Timer erstellen, wird die Rückrufmethode wie folgt definiert:

-(void)someMethod:(NSTimer*)timer;

Wenn Sie also den Timer einplanen, geben Sie mit @selector an, welche Methode in Ihrem Objekt tatsächlich für den Rückruf verantwortlich ist:

@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;
}

In diesem Fall geben Sie an, dass das Objekt alle 30 Sekunden mit myTimerCallback gemeldet werden soll.

100
Jason Coco

Sie können in @selector () keinen Parameter übergeben.

Sie versuchen anscheinend, einen Rückruf zu implementieren. Der beste Weg, das zu tun, wäre etwa so:

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

Dann können Sie in der setCallbackObject: withSelector: -Methode Ihres Objekts Ihre Callback-Methode aufrufen.

-(void)setCallbackObject:(id)anObject withSelector:(SEL)selector {
    [anObject performSelector:selector];
}
18
Grant Limberg

Abgesehen von dem, was bereits über Selektoren gesagt wurde, sollten Sie sich die NSInvocation-Klasse ansehen.

Eine NSInvocation-Nachricht ist eine statisch gemachte Objective-C-Nachricht, dh eine Aktion, die in ein Objekt umgewandelt wird. NSInvocation-Objekte werden zum Speichern und Weiterleiten von Nachrichten zwischen Objekten und zwischen Anwendungen verwendet, hauptsächlich von NSTimer-Objekten und den verteilten Objekten System.

Ein NSInvocation-Objekt enthält alle Elemente einer Objective-C-Nachricht: ein Ziel, einen Selektor, Argumente und den Rückgabewert. Jedes dieser Elemente kann direkt festgelegt werden, und der Rückgabewert wird beim NSInvocation automatisch festgelegt Objekt wird versandt.

Beachten Sie, dass NSInvocation in bestimmten Situationen zwar nützlich ist, Sie es jedoch an einem normalen Codierungstag nicht verwenden. Wenn Sie nur versuchen, zwei Objekte miteinander zu kommunizieren, sollten Sie ein informelles oder formelles Delegierungsprotokoll definieren oder einen Selektor und ein Zielobjekt übergeben, wie bereits erwähnt.

5