2012-11-02 8 views

risposta

7

Questo funziona, ma è un po 'un anti-pattern. Quello che vorrei fare è lanciare un errore se il thread su cui è chiamato il metodo non è il thread principale. È responsabilità del chiamante assicurarsi che i metodi siano richiamati sui thread corretti, questi tipi di hack incoraggiano solo il brutto codice. Inoltre, se ti affidi a questo, all'improvviso raddoppi il costo di invio dei messaggi per ogni volta che chiami questo metodo.

Se davvero potete modificare il comportamento del chiamante, si può provare il seguente:

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

questo farà sì che tutto il codice all'interno del blocco di spedizione che deve essere eseguito sul thread principale, e il metodo non tornerà fino è completo Se si desidera che il metodo restituisca immediatamente, è possibile utilizzare invece dispatch_async. Se si utilizza dispatch_sync, è possibile utilizzare questo trucco anche su metodi con tipi di reso non vuoto.

Questo codice ha anche il vantaggio di supportare i metodi con argomenti che non sono di tipo oggetto (int ecc.). Supporta anche metodi con un numero arbitrario di argomenti, mentre performSelector:withObject: e i suoi metodi di parentela supportano solo un numero limitato di argomenti. L'alternativa è impostare gli oggetti NSInvocation e quelli sono un dolore.

Si noti che questo richiede Grand Central Dispatch (GCD) sulla piattaforma.

+0

+1 per l'alternativa typesable – justin

3

_cmd inoltro va bene, a patto che il selettore specificato dal _cmd corrisponde alla definizione/firma specificato nella documentazione: "Il metodo non dovrebbe avere un valore di ritorno significativo e dovrebbe prendere un singolo argomento di tipo ID, o nessuna argomenti.". Se non corrisponde, allora dovresti assumere un comportamento indefinito. E per essere sicuro al 110% e aderire alla macchina astratta, il tipo restituito deve essere id (o qualche tipo objc), e il risultato non dovrebbe restituire un riferimento proprietario.

+1

+1 per la annotazione delle restrizioni. Ho ignorato il problema del tipo restituito nella mia risposta perché il metodo originale nella domanda è un 'void', ma OP sembra cercare una soluzione generale e' performSelector' non è uno. – yfrancis

+0

@yfrancis inizialmente ho evitato di menzionare anche il tipo restituito :) ma ne ho aggiunto un po 'in una modifica. – justin

Problemi correlati