34

En AppDelegate, estoy asignando una instancia definida en una biblioteca estática. Esta instancia tiene una propiedad NSString configurada como "copia". Cuando accedo a la propiedad de cadena en esta instancia, la aplicación falla con 'selector no reconocido enviado a instancia'. Xcode proporciona una sugerencia de código para la propiedad, lo que significa que se conoce en la aplicación de llamada. La clase particular se compila en el objetivo de la biblioteca estática. ¿Qué me estoy perdiendo?¿Cómo resolver el 'selector no reconocido enviado a la instancia'?

Agregando un código.

//static library 
//ClassA.h 
@interface ClassA : NSObject { 
... 
NSString *downloadUrl; 
} 
@property(nonatomic, copy) NSString *downloadUrl; 

//ClassA.m 
@synthesize downloadUrl; 

En la aplicación de la aplicación que llamaDelegate.

//app delegate header file 
@interface myApp : NSObject <UIApplicationDelegate> { 
ClassA *classA; 
} 
@property (nonatomic, retain) ClassA *classA; 

//app delegate .m file 
@synthesize classA; 

- (void)applicationDidFinishLaunching:(UIApplication *)application { 
classA = [[ClassA alloc] init]; 
//exception occurs here. downloadUrl is of type NSCFNumber 
classA.downloadUrl = @"http://www.abc.com/"; 
...} 

Otras clases de la aplicación obtendrá una referencia al delegado y llamar a classA.downloadUrl.

+2

Creo que usted necesita para enviar fragmentos de código y el mensaje de error completo para obtener mucha ayuda aquí. – smorgan

Respuesta

25

1) ¿Está la sintetización dentro del bloque @implementation?

2) ¿Debería consultar self.classA = [[ClassA alloc] init]; y self.classA.downloadUrl = @"..." en lugar de simplemente classA?

3) En su archivo myApp.m necesita importar ClassA.h, cuando falta, ¿usará un número o un puntero? (en variables C por defecto a int si el compilador no lo encuentra):

#import "ClassA.h".

+1

Ya lo he intentado. Todavía obtienes una excepción. Tengo varias otras clases similares en la misma biblioteca. Ninguno de ellos está teniendo este problema. – 4thSpace

+0

¿Has probado [classA setDownloadUrl: @ "http://www.abc.com/"]; ....? – stefanB

+0

... Por supuesto, el 'www' se acortó al enlace web en el comentario anterior – stefanB

1

En el código que envió, va a enviar el colocador setDownloadURL: a ClassA - es decir, la clase en sí . Desea establecer la propiedad de una instancia.

+0

En la clase estática, tengo @property (nonatomic, copy) NSString * theString y theString es @synthesize. ¿Hay algo más? – 4thSpace

+0

Me doy cuenta cuando muevo el mouse sobre theString en el lado de la persona que llama, su tipo es NSCFNumber. Debería ser NSString. – 4thSpace

+0

¿cómo se accede? – stefanB

1

¿Cómo se está importando ClassA en su clase de AppDelegate? ¿Incluyó el archivo .h en el proyecto principal? Tuve este problema por un tiempo porque no copié el archivo de encabezado en el proyecto principal, así como el #include normal "ClassA.h".

Copiando, o creando el .h lo resolvió para mí.

+0

En la biblioteca, tengo un .h que hace referencia a todos los demás archivos .h. Por lo tanto, la aplicación de llamada solo necesita hacer referencia a ese archivo .h particular para obtener una referencia a todo en la biblioteca. Puedo arrastrar el archivo de encabezado ClassA al proyecto de la aplicación y referenciarlo desde el archivo .m. Aún así, obtienes la misma excepción. – 4thSpace

+0

Otra cosa que puede intentar es hacer self.classA.downloadUrl. Ese error generalmente es lo que obtienes cuando una variable se inicializa a nada, como NSString * m. Se establece en un int aparentemente aleatorio. Puede intentar anular el método init en la clase y configurarlo en cero allí. –

+0

He intentado anular init pero mi punto de interrupción allí nunca es golpeado. Sin embargo, si paso a Definición en ClassA donde está el alloc, va al archivo correcto y veo mi init personalizado. – 4thSpace

0

Debe tener en cuenta que este no es necesariamente el mejor patrón de diseño. Por lo que se ve, esencialmente estás usando tu delegado de aplicaciones para almacenar lo que equivale a una variable global.

Matt Gallagher cubrió bien el tema de los globals en su artículo Cocoa with Love en http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html. Probablemente, su ClassA debería ser un singleton en lugar de un global en AppDelegate, aunque es posible que intente que ClassA sea más general y no simplemente singleton. En ese caso, probablemente sería mejor, ya sea con un método de clase para devolver una instancia preconfigurada de Clase A, algo así como:

+ (ClassA*) applicationClassA 
{ 
    static ClassA* appClassA = nil; 
    if (!appClassA) { 
     appClassA = [[ClassA alloc] init]; 
     appClassA.downloadURL = @"http://www.abc.com/"; 
    } 
    return appClassA; 
} 

O, alternativamente, (ya que añadiría materia de aplicación específica a lo que es posiblemente una clase de propósito general), crea una nueva clase cuyo único propósito es contener ese método de clase.

El punto es que las aplicaciones globales no necesitan ser parte de AppDelegate. El hecho de que AppDelegate sea un singleton conocido, no significa que todas las demás aplicaciones globales se mezclen con él, incluso si no tienen nada que ver conceptualmente con el manejo de los métodos delegados de NSApplication.

+1

Irrelevante para emitir a la mano. – Justicle

18

Establecer la bandera -ObjC en Otro enlazador Marcar en su configuración de Proyecto ...(No en el proyecto de biblioteca estática pero el proyecto que está utilizando la biblioteca estática ...) Y asegúrese de que en Configuración del proyecto la configuración esté establecida en Toda la configuración

+0

Acabo de crear una biblioteca estática con un objetivo unittest en Xcode4.2. Tuve que agregar "-ObjC" a "Otras banderas de enlace". Ahora la prueba unitaria se ejecuta. – neoneye

+0

¡Esa fue la solución para mí! Gracias. – Xtro

0

Muy raro, pero. Debe declarar la clase para su instancia de aplicación como myApplication: UIApplication en lugar de myApplication: NSObject. Parece que el protocolo UIApplicationDelegate no implementa el mensaje + registerForSystemEvents. Crazy Apple APIs, de nuevo.

14

Mucha gente ha dado algunas respuestas muy técnicas para esta y otras preguntas similares, pero creo que es más simple que eso. Algunas veces, si no está prestando atención, un selector que no tiene la intención de usar se puede adjuntar a algo en la interfaz. Es posible que esté recibiendo este error porque el selector está allí pero no ha escrito ningún código para él.

La manera más fácil de verificar que este no es el caso es presionando la tecla Control para hacer clic en el elemento para que pueda ver todos los selectores que están asociados. Si hay algo allí que no quieres ser, ¡deshazte de él! Espero que esto ayude ...

+0

Al final de un largo día, esto era exactamente lo que necesitaba ver. Gracias por mantenerlo simple. – jeremytripp

+0

Acabo de tener esto en mi primer proyecto de iOS. Tenía un "enlace" muerto a una implementación de acción en mi controlador de vista. Lo eliminó, y funcionó. ¡Gracias! –

+0

Bingo - ¡exactamente lo que necesitaba! ¡Gracias! – Kenny

1

Para mí, lo que causó este error fue que accidentalmente tuve el mismo mensaje enviado dos veces al mismo miembro de la clase. Cuando hice clic derecho en el botón de la interfaz gráfica de usuario, pude ver el nombre del método dos veces, y acabo de eliminar uno. Error de principiante en mi caso, pero quería sacarlo para que otros novatos lo tengan en cuenta.

1

El mío era algo simple/estúpido. Error de principiante, para cualquiera que haya convertido su NSManagedObject a un NSObject normal.

tuve:

@dynamic order_id; 

cuando debería haber tenido:

@synthesize order_id; 
Cuestiones relacionadas