2012-01-07 10 views
10

sto ricevendo un avvisoperformSelector avvertimento

performSelector può causare una perdita perché il suo selettore è sconosciuta

Nel codice:

- (void) callDelegate: (SEL) selector withArg: (id) arg error: (NSError*) err 
{ 
    assert([NSThread isMainThread]); 
    if([delegate respondsToSelector: selector]) 
    { 
     if(arg != NULL) 
     { 
      //this line the warning 
      [delegate performSelector: selector 
          withObject: arg 
          withObject: err]; 
     } 
     else 
     { 
      //this line the warning 
      [delegate performSelector: selector 
          withObject: err]; 
     } 
    } 
    else 
    { 
     NSLog(@"Missed Method"); 
    } 
} 

Intestazione:

@interface Topscore : UIViewController <NSObject> { 

// 
} 
+0

possibile duplicato del [performSelector può causare una perdita perché il suo selettore è sconosciuta] (http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak- perché-suo-selettore-è-sconosciuto) –

+0

Penso che questo [buon post] (http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown) spiega il problema molto bene! Potrebbe essere utile! – monjer

risposta

4

Questo è un avviso generato dal compilatore poiché è stato utilizzato -Wundeclared-selector durante la compilazione e il conteggio del riferimento automatico (ARC) è abilitato. Questo può, in generale, essere ignorato in modo sicuro, poiché è ovvio che il selettore nella variabile denominata "selettore" è sconosciuto al momento della compilazione, in quanto avrà il suo valore assegnato in fase di runtime.

+0

Grazie ma nella mia app restituisce NSLOG; Metodo perso Questo è sbagliato – Blazer

+0

Ciò significa che l'oggetto non implementa tale metodo (quindi non risponde al selettore specificato). Quindi NON causa una perdita di memoria, perché se viene raggiunto il ramo "else" della struttura if, il metodo - [delegeta performSelector] non è stato invocato, quindi non è riuscito a conservare l'oggetto, quindi non vi sono perdite di memoria. –

+0

Hai ricordato di mettere i due punti dietro il selettore per ogni argomento? Il selettore per '- (void) methodWithObject: (id) arg1;' in realtà è '@selector (methodWithObject:)'. Il colon è parte di esso. – weezor

42

Il tuo if ... respondsToSelector: selector non funziona perché il tuo selector è solo il nome del metodo. Per il vostro caso è necessario verificare

if ([delegate respondsToSelector: @selector(method::)] 

e per l'altro caso solo per method:.

In ogni caso, è possibile sopprimere l'avviso in questo modo:

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Warc-performSelector-leaks" 
    [self performSelector:nextView]; 
#pragma clang diagnostic pop 
+1

Ignorando selettivamente l'avviso è super pratico . Grazie. – Megasaur

+5

Ho capito che è sufficiente usare '#pragma clang diagnostic ignored" -Warc-performSelector-leaks "' all'inizio dell'implementazione della classe. –

+2

@ Julian ma poi non sai se c'è un vero problema da qualche altra parte nella tua implementazione di classe.D'altra parte è possibile disattivare l'avviso a livello globale nelle impostazioni di costruzione, se non ti dispiace ... – Klaas

3

È anche possibile utilizzare objc_msgSend invece di performSelector, come descritto here.

+2

Ma sembra essere un overkill ... – ZhangChn

+0

Perché eccessivo? È solo un altro modo di fare la stessa cosa, vero? –

3

si potrebbe aggiungere -Wno-arco performSelector-leaks per WARNING_CFLAGS nel Build Settings. enter image description here

Found the solution here

0

Il modo più semplice è l'aggiunta di questa macro per il vostro file PCH. O un file .m ..

#pragma GCC diagnostic ignored "-Wundeclared-selector" 
Problemi correlati