estoy corriendo en un tema extraño en Objective-C cuando tengo dos clases usando inicializadores del mismo nombre, pero los argumentos escritos de manera diferente. Por ejemplo, digamos que crear clases A y B:¿Los inicializadores de Objective-C tienen permitido compartir el mismo nombre?
A.h:
#import <Cocoa/Cocoa.h>
@interface A : NSObject {
}
- (id)initWithNum:(float)theNum;
@end
a.m:
#import "A.h"
@implementation A
- (id)initWithNum:(float)theNum
{
self = [super init];
if (self != nil) {
NSLog(@"A: %f", theNum);
}
return self;
}
@end
B.h:
#import <Cocoa/Cocoa.h>
@interface B : NSObject {
}
- (id)initWithNum:(int)theNum;
@end
Bm:
#import "B.h"
@implementation B
- (id)initWithNum:(int)theNum
{
self = [super init];
if (self != nil) {
NSLog(@"B: %d", theNum);
}
return self;
}
@end
main.m:
#import <Foundation/Foundation.h>
#import "A.h"
#import "B.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
A *a = [[A alloc] initWithNum:20.0f];
B *b = [[B alloc] initWithNum:10];
[a release];
[b release];
[pool drain];
return 0;
}
Cuando ejecuto esto, me da el siguiente resultado:
2010-04-26 20:44:06.820 FnTest[14617:a0f] A: 20.000000
2010-04-26 20:44:06.823 FnTest[14617:a0f] B: 1
Si invierto el orden del las importaciones por lo que importa Bh primera, me sale:
2010-04-26 20:45:03.034 FnTest[14635:a0f] A: 0.000000
2010-04-26 20:45:03.038 FnTest[14635:a0f] B: 10
Por alguna razón, parece que se trata de utilizar el tipo de datos definido en lo que @interface se incluyó por primera vez para ambas clases. Hice algunos pasos a través del depurador y descubrí que el puntero isa para los objetos ayb termina igual. También descubrí que si yo ya no hago el alloc e init llamadas en línea, ambas inicializaciones parecen funcionar correctamente, por ejemplo:
A *a = [A alloc];
[a initWithNum:20.0f];
Si utilizo esta convención cuando creo que tanto a como b, me sale la derecha salida y los punteros isa parecen ser diferentes para cada objeto.
¿Estoy haciendo algo mal? Hubiera pensado que varias clases podrían tener los mismos nombres de inicializador, pero quizás ese no sea el caso.
También puede agregar estática 'typeWithArgument:' métodos, como '[NSNumber numberWithInt:]' para desambiguar – drawnonward
De acuerdo con la documentación, el 'Ivar isa' debe establecerse cuando se llama' + [alloc NSObject] '. Dado que los envíos de mensajes de Objective-C se resuelven en tiempo de ejecución, no es que el trabajo del tiempo de ejecución, no el trabajo del compilador, de averiguar qué '+ [A alloc]' resuelve? –
@Nick Forge: la implementación está vinculada dinámicamente, por lo que no es un problema (y eso es cierto aquí ya que el NSLog muestra A y B como se esperaba). Donde el compilador está involucrado está en construir la llamada a obj_msgSend. En este caso, un selector usa un flotante mientras que el otro usa un entero, y el compilador genera instrucciones diferentes (almacenando el int en un registro entero y el float en un registro fp). Debido a esto, la implementación del método encuentra datos erróneos en el registro esperado. –