2012-01-07 12 views
10

Estoy recibiendo una advertenciaPerformSelector advertencia

PerformSelector puede causar una fuga debido a su selector se desconoce

En el código:

- (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"); 
    } 
} 

Cabecera:

@interface Topscore : UIViewController <NSObject> { 

// 
} 
+0

posible duplicado de [performSelector puede causar una fuga debido a su selector es desconocida] (http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak- porque-su-selector-es-desconocido) –

+0

Creo que esta [buena publicación] (http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown ¡Explica el problema muy bien! ¡Puede ser útil! – monjer

Respuesta

4

Esta es una advertencia generada por el compilador porque -Wondeclared-selector se utilizó durante la compilación y el conteo automático de referencias (ARC) está habilitado. Esto puede, en general, ignorarse de forma segura, ya que es obvio que el selector en la variable llamada "selector" es desconocido en tiempo de compilación, ya que tendrá su valor asignado en tiempo de ejecución.

+0

Gracias pero en mi aplicación devuelve el NSLOG; Método perdido. Esto está mal – Blazer

+0

Eso significa que el objeto no implementa ese método (por lo tanto, no responde al selector especificado). NO provoca una pérdida de memoria, porque si se llega a la rama "else" de la estructura if, no se ha invocado el método - [delegeta performSelector], por lo que no pudo retener el objeto, por lo que no hay pérdidas de memoria. –

+0

¿Recordó poner dos puntos detrás del selector para cada argumento? El selector para '- (void) methodWithObject: (id) arg1;' en realidad es '@selector (methodWithObject:)'. El colon es parte de eso. – weezor

42

Su if ... respondsToSelector: selector no funcionará porque su selector es solo el nombre del método. Para su caso es necesario comprobar

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

y por el otro caso sólo para method:.

De todos modos, se puede suprimir la advertencia como esta:

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

Ignorar de forma selectiva la advertencia es muy útil . Gracias. – Megasaur

+5

Descubrí que es suficiente utilizar '#pragma clang diagnostic ignored" -Warc-performSelector-leaks "' al comienzo de la implementación de la clase. –

+2

@Julian, pero entonces no se sabe si hay un problema real en otro lugar en la implementación de su clase.Por otro lado, puedes desactivar la advertencia globalmente en tu configuración de compilación si no te importa ... – Klaas

3

También se puede utilizar en lugar de objc_msgSend performSelector, tal como se describe here.

+2

Pero parece ser una exageración ... – ZhangChn

+0

¿Por qué exagerar? Es solo otra forma de hacer lo mismo, ¿no? –

3

Se podría añadir -Wno-arc-performSelector-fugas para WARNING_CFLAGS en el Build Settings. enter image description here

Found the solution here

0

La manera más fácil es añadir esta macro para su archivo PCH. O un archivo .m ..

#pragma GCC diagnostic ignored "-Wundeclared-selector" 
Cuestiones relacionadas