2012-11-02 5 views

Antwort

7

Das funktioniert, ist aber ein bisschen ein Anti-Pattern. Was ich tun würde, ist einen Fehler zu werfen, wenn der Thread, auf den die Methode aufgerufen wird, nicht der Hauptthread ist. Es liegt in der Verantwortung des Aufrufers sicherzustellen, dass Methoden auf den richtigen Threads aufgerufen werden, diese Arten von Hacks fördern nur hässlichen Code. Wenn Sie sich darauf verlassen, verdoppeln Sie plötzlich den Overhead für die Nachrichtenübermittlung bei jedem Aufruf dieser Methode.

Wenn Sie wirklich kippen das Verhalten des Anrufers ändern, können Sie versuchen, die folgenden:

-(void)methodToBeRunOnMainThreadWithObj:(id)object { 
    dispatch_sync(dispatch_get_main_queue(), ^{ 
     // code goes here 
    }); 
} 

all Code innerhalb der Abfertigungs-Blöcke verursachen wird auf dem Haupt-Thread ausgeführt werden, und das Verfahren kehrt erst Es ist vollständig. Wenn Sie möchten, dass die Methode sofort zurückkehrt, können Sie stattdessen dispatch_async verwenden. Wenn Sie dispatch_sync verwenden, können Sie diesen Trick auch für Methoden verwenden, die nicht leere Rückgabetypen aufweisen.

Dieser Code hat auch den zusätzlichen Vorteil der Unterstützung von Methoden mit Argumenten, die von Nicht-Objekttypen sind (int usw.). Es unterstützt auch Methoden mit einer beliebigen Anzahl von Argumenten, während und seine Geschwistermethoden nur eine begrenzte Anzahl von Argumenten unterstützen. Die Alternative ist, NSInvocation Objekte einzurichten und diese sind ein Schmerz.

Beachten Sie, dass dies Grand Central Dispatch (GCD) auf Ihrer Plattform erfordert.

+0

+1 für die typsichere Alternative – justin

3

_cmd Forwarding ist in Ordnung, solange der von _cmd angegebenen Selektor in der Dokumentation angegeben, die Definition/Signatur übereinstimmt: „Das Verfahren keinen wesentlichen Rückgabewert und soll ein einzelnes Argument vom Typ id nehmen soll, oder nicht Argumente.". Wenn es nicht übereinstimmt, sollten Sie ein nicht definiertes Verhalten annehmen. Und um 110% sicher zu sein und der abstrakten Maschine zu folgen, sollte der Rückgabetyp id (oder irgendein objc-Typ) sein, und das Ergebnis sollte keine besitzende Referenz zurückgeben.

+1

+1 für die Notierung der Einschränkungen. Ich ignorierte das Rückgabetyp-Problem in meiner Antwort, weil die ursprüngliche Methode in der Frage ein "void" ist, aber OP scheint nach einer allgemeinen Lösung zu suchen, und "performSelector" ist keiner. – yfrancis

+0

@yfrancis Ich vermied anfangs auch, den Rückgabetyp zu erwähnen :), aber ich fügte ein bisschen darüber in einem Schnitt hinzu. – justin

Verwandte Themen