Usando#pragma para suprimir las advertencias de "Método de instancia no encontrado" en Xcode
gcc warnings (4)
Quiero usar #pragma
(en Xcode) para suprimir la advertencia:
advertencia: no se encontró el método de instancia ''-someMethod'' (el tipo de retorno está predeterminado en ''id'')
He intentado:
#pragma GCC diagnostic ignored "-Wmissing-declarations"
Y varios otros, pero nada funciona.
¿Qué advertencia causa el "método de instancia no encontrado"?
Editar
Como se solicita aquí está el código real:
...
if (sampleRate > 0 && ![self isFinishing]) //<--- Warning here
{
return self.progress;
}
...
Y la salida de registro de compilación:
/Users/User1/Documents/Project/branch/client/Folder/CodeFile.m:26:32:{26:32-26:50}: warning: instance method ''-isFinishing'' not found (return type defaults to ''id'') [3]
if (sampleRate > 0 && ![self isFinishing])
^~~~~~~~~~~~~~~~~~
El enlace de Pavan es bueno, pero también podría haber una respuesta más simple y obvia. ¿Es su método isFinishing en su archivo .m pero declarado después de su uso (donde recibe la advertencia)? Si es así, mueva la declaración antes de su uso. Si ese simple caso no es la respuesta que podría desear, puede usar una categoría para informar al compilador sobre este método. Frecuentemente hago esto para probar métodos "privados". Otra opción es usar un indicador de compilación para este archivo para suprimir esta advertencia para todo el archivo. Sé que ninguno de ellos especifica cómo resolver esto con un pragma, pero es posible que encuentre otra solución viable.
OK, yo otra vez :) Probé varios #pragma
s ''clang'' específicos pero nada funcionó, y lo único que se me ocurrió fue declarar el método como un ''método privado'' dentro de la clase que realmente usa el método, por lo tanto:
main.m:
#import <Foundation/Foundation.h>
#import "PragmaTest.h"
@interface PragmaTest ()
- (void)noSuchMethod;
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
PragmaTest *pragmaTest = [[PragmaTest alloc] init];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wall"
[pragmaTest noSuchMethod];
#pragma clang diagnostic pop
[pragmaTest release];
// insert code here...
NSLog(@"Hello, World!");
}
return 0;
}
PragmaTest.h:
#import <Foundation/Foundation.h>
@interface PragmaTest : NSObject
@end
PragmaTest.m:
#import "PragmaTest.h"
@implementation PragmaTest
- (void)noSuchMethod
{
NSLog(@"noSuchMethod");
}
@end
Espero que esto cumpla con sus requisitos y aunque no es una solución que implique #pragma
s, espero que no sienta la necesidad de rechazar una respuesta útil.
¿Qué advertencia causa el "método de instancia no encontrado"?
Eso es -Wobjc-method-access
, así que intenta
#pragma GCC diagnostic ignored "-Wobjc-method-access"
o compile ese archivo con -Wno-objc-method-access
para solo suprimir esa advertencia.
Ambas soluciones tienen la limitación de que se aplicarán a todo el archivo, que generalmente no es lo que desea. clang
te ofrece una alternativa aún mejor:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-method-access"
if (sampleRate > 0 && ![self isFinishing])
{
return self.progress;
}
#pragma clang diagnostic pop
El primer pragma guarda todos los indicadores de advertencia actuales en una pila interna, luego configura esta advertencia para que el código la ignore y, después de ese código, la última línea mostrará el estado guardado y restablecerá de nuevo todos los indicadores de advertencia.
Ten en cuenta que el hecho de que recibas tal advertencia significa que hay algo sospechoso en tu código. O este método realmente no existe, en ese caso no deberías llamarlo, o existirá en tiempo de ejecución, simplemente olvidaste contarlo al compilador.
En primer lugar, debe hacer que su código sea seguro porque llamar a un método no existente generalmente bloqueará su aplicación:
if (sampleRate > 0
&& ([self respondsToSelector:@selector(isFinishing)]
&& ![self isFinishing]
)
) {
return self.progress;
}
Este código primero prueba si la llamada es isFinishing
o está fatal. Solo si está bien la llamada se realiza realmente.
Ahora el compilador todavía necesita saber sobre el método isFinishing
, no solo que existe sino también lo que devuelve. El código de máquina para ![self isFinishing]
no es necesariamente el mismo para un método que devuelve un bool, devuelve un entero, devuelve un doble o devuelve un objeto (o cualquier otro tipo de puntero). El compilador solo puede generar el código correcto si conoce el prototipo de ese método. La forma más fácil es usar una propiedad para eso. Puede declarar esa propiedad en su archivo fuente (el archivo .m) si no desea exponerlo en su archivo de encabezado (el archivo .h), solo debe declararlo en una extensión de clase (que es básicamente una categoría sin nombre):
@interface YourClass ( )
@property (readonly) BOOL isFinishing;
@end
@implementation YourClass
// Implementation of the class follows here
Ahora el compilador sabe que isFinishing
devuelve un BOOL
. Y para evitar que el compilador genere cualquier código para esa propiedad, póngalo en la implementación:
@dynamic isFinishing;
Esto le dice al compilador que no haga nada por esa propiedad (no cree un ivar, no cree un getter) y simplemente suponga que en el tiempo de ejecución isFinishing
un método llamado isFinishing
(el compilador no hará ningún código para verificar en tiempo de ejecución ¡confía en tu palabra!)
Consulte: https://.com/a/34043306/89035 para un #pragma para suprimir las advertencias de "método de instancia no encontrado".
Si bien parece que no existe una verdadera solución #pragma
para esto, desactivar las advertencias en archivos individuales se puede lograr mediante el uso del -w
.
NB: esta solución es para Xcode 4.2 y superior
- Seleccione el objetivo
- Haga clic en la pestaña "Crear fases"
- En "Compilar fuentes", agregue el interruptor
-w
a los archivos que desea suprimir las advertencias en