Für dieses sehr einfache Beispiel in der Frage, da
[object doSomething];
[object performSelector:@selector(doSomething)];
gibt keinen Unterschied in dem, was passieren wird. doSomething wird synchron per Objekt ausgeführt. Nur "doSomething" ist eine sehr einfache Methode, die nichts zurückgibt und keine Parameter benötigt.
es etwas ein wenig komplizierter, wie:
(void)doSomethingWithMyAge:(NSUInteger)age;
Dinge wäre kompliziert, weil [Objekt doSomethingWithMyAge: 42];
kann mit keiner Variante von "performSelector" mehr aufgerufen werden, da alle Varianten mit Parametern nur Objektparameter akzeptieren.
Der Wähler hier wäre "doSomethingWithMyAge:" sein, aber jeder Versuch,
[object performSelector:@selector(doSomethingWithMyAge:) withObject:42];
einfach nicht kompilieren. Die Übergabe einer NSNummer: @ (42) anstelle von 42 würde ebenfalls nicht helfen, da die Methode einen grundlegenden C-Typ erwartet - kein Objekt.
Darüber hinaus gibt es performSelector Varianten bis zu 2 Parameter, nicht mehr. Während Methoden viele Male mehr Parameter haben.
Ich habe herausgefunden, dass, obwohl synchrone Varianten von perform:
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
immer ein Objekt zurückgeben, konnte ich auch ein einfaches BOOL oder NSUInteger zurückzukehren, und es funktionierte.
Eine der zwei Hauptverwendungen von performSelector besteht darin, den Namen der Methode, die Sie ausführen möchten, dynamisch zu erstellen, wie in einer vorherigen Antwort erläutert. Zum Beispiel
SEL method = NSSelectorFromString([NSString stringWithFormat:@"doSomethingWithMy%@:", @"Age");
[object performSelector:method];
Die andere Verwendung ist asynchron eine Nachricht versenden zu widersprechen, die später auf dem aktuellen Runloop ausgeführt werden. Dafür gibt es mehrere andere performSelector-Varianten.
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
- (void)performSelector:(SEL)aSelector target:(id)target argument:(id)arg order:(NSUInteger)order modes:(NSArray *)modes;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;
(ja, ich sammelte sie aus mehreren Foundation Klassenkategorien, wie NSThread, NSRunLoop und NSObject)
Jede der Varianten sein eigenes spezielles Verhalten, aber alle teilen etwas gemeinsam (zumindest, wenn waitUntilDone ist auf NEIN eingestellt). Der Aufruf "performSelector" würde sofort zurückkehren, und die Nachricht zum Objekt wird erst nach einiger Zeit auf den aktuellen Runloop gesetzt.
Wegen der verzögerten Ausführung - natürlich ist kein Rückgabewert aus der Methode des Selektors verfügbar, daher der Rückgabewert - (void) in allen diesen asynchronen Varianten.
Ich hoffe, dass ich das irgendwie bedeckt ...
Es lohnt Hinweis darauf, dass Sie tatsächlich das Ergebnis von findTheAppropriateSelectorForTheCurrentSituation(), um aSelector zuweisen, rufen Sie dann [anObject perform: aSelector]. @selector erzeugt ein SEL. –
Die Verwendung von 'performSelector:' ist etwas, was Sie wahrscheinlich nur tun, wenn Sie eine Zielaktion in Ihrer Klasse implementieren. Die Geschwister 'performSelectorInBackground: withObject:' und 'performSelectorOnMainThread: withObject: waitUntilDone:' sind oft nützlicher. Zum Erstellen eines Hintergrundthreads und zum Zurückrufen von Ergebnissen zum Hauptthread von diesem Hintergrundthread. – PeyloW
'performSelector' ist auch nützlich, um Kompilierungswarnungen zu unterdrücken. Wenn Sie wissen, dass die Methode existiert (wie nach der Verwendung von 'reaymToSelector'), wird Xcode davon abhalten zu sagen," kann nicht auf 'your_selector' antworten". Benutze es nicht, anstatt die wahre Ursache der Warnung herauszufinden.;) – Marc