2008-11-23 11 views
5

que posean un método init que toma un (id) argumento:¿Por qué tengo que lanzarme a la identificación?


    -(id) initWithObject:(id) obj; 

Estoy intentando llamar así:


    [[MyClass alloc] initWithObject:self]; 

Pero XCode se queja el argumento de ser un "distinta Tipo Objective-C "(que generalmente indica una discrepancia de tipo o un nivel de error indirecto).

Si me lanzo explícitamente a (id), la advertencia desaparece. En cualquier caso, el código se ejecuta como se esperaba. Curiosamente, en la siguiente línea me estoy pasando a otro método que también toma una identificación, y eso funciona bien.

Me pregunto si me falta algo sutil, ¿o es una peculiaridad del compilador?

No me siento del todo cómodo simplemente lanzándolo hasta que esté seguro de las razones por las que es necesario.

[Editar]

Me han pedido para suministrar más código. No estoy seguro de que haya mucho más relevante. Aquí está mi código real que hace la llamada. Tenga en cuenta que es, en sí mismo, dentro de un método init. Es la llamada a initWithSource que está dando la advertencia:


-(id) initWithFrame:(CGRect) frame 
{ 
    self = [super initWithFrame: frame]; 
    if(self) 
    { 
     delegate = nil; 
     touchDelegate = [[TBCTouchDelegate alloc] initWithSource:self]; 
     [touchDelegate.viewWasTappedEvent addTarget: self action:@selector(viewWasTapped:)]; 
    } 
    return self; 
} 

Y aquí está el método init se llama:


-(id) initWithSource:(id) sourceObject 
{ 
    self = [super init]; 
    if (self != nil) 
    { 
     // Uninteresting initialisation snipped 
    } 
    return self; 
} 
+0

Es posible que desee publicar más código aquí; nada está saltando, pero con solo dos líneas para trabajar, es difícil de decir. –

+0

De acuerdo con Ben, pero una cosa a tener en cuenta, ¿está declarado el método initWithObject? –

+0

Gracias por mirar, muchachos. He agregado un poco más de código arriba, por lo que vale. @Jason: Sí, initWithSource (el nombre de mi método real) se declara en el encabezado y definitivamente coincide. – philsquared

Respuesta

7

Normalmente, esto significa que hay varios nombres initWithSource: método en diferentes clases con tipos de argumentos contradictorios. Recuerde, si una variable se escribe como id, el compilador no sabe de qué clase se trata. Por lo tanto, si llama al initWithSource: en un objeto tipo id y las clases múltiples tienen un método initWithSource:, el compilador solo elige uno de los dos. Si escoge el que está "equivocado", bueno, se obtiene un error de "tipo Objective-C distinto".

Entonces, ¿por qué te está pasando esto? No estoy 100% seguro, pero recuerda que +[TBCTouchDelegate alloc] devuelve un id. Así encadenar el alloc/init llama es equivalente a esto:

id o = [TBCTouchDelegate alloc]; 
touchDelegate = [o initWithSource:self]; 

Por lo tanto, a la que llama initWithSource: en una variable -typed id. Si hay un método en conflicto initWithSource:, puede obtener este error de compilación.

¿Hay un método conflictivo? Comprobé el sistema, y ​​el único que estaba en conflicto NSAppleScript:

- (id)initWithSource:(NSString *)source; 

ahora NSAppleScript es parte de la Fundación, pero me di cuenta de esto es el código iPhone. Entonces, ¿tal vez solo obtiene este error al compilar para el simulador, y no el dispositivo?

En cualquier caso, si este es su problema, usted podría conseguir alrededor de él mediante la división alloc/init en dos líneas diferentes:

touchDelegate = [TBCTouchDelegate alloc]; 
touchDelegate = [touchDelegate initWithSource:self]; 

Ahora, que está llamando initWithSource: en una variable de tipo totalmente (en lugar de id -typed), por lo que el compilador ya no tiene que adivinar cuál elegir. O bien, podría emitir el regreso de +alloc:

touchDelegate = [(TBCTouchDelegate *)[TBCTouchDelegate alloc] initWithSource:self]; 

Otra solución es cambiar el nombre initWithSource: para evitar el conflicto y tal vez hacer que sea más descriptivo. No dices para qué se llama actualmente la clase ni para qué sirve la "fuente", así que no puedo descartar ninguna posibilidad.

+0

Intenté copiar el código en mi propio proyecto y comando-doble-clic en initWithSource. A pesar de ser un proyecto de iPhone, de hecho está intentando hacer referencia a NSApplescript, según la sugerencia de Dave. –

+0

Gracias Dave, eso fue perfecto, ¡y claramente explicado también! Afortunadamente, la palabra "fuente" fue bastante arbitraria, por lo que he podido cambiarla con bastante facilidad. TouchDelegate es un proxy para toques de eventos, y el "origen" es el objeto para el que está realizando el proxy. Lo he llamado TouchSource ahora. – philsquared

+0

Gracias por la confirmación adicional también, Ben, y por tomarse el tiempo para ayudar. – philsquared

Cuestiones relacionadas