Je rencontre un problème étrange en Objective-C quand j'ai deux classes utilisant des initialiseurs du même nom, mais des arguments typés différemment. Par exemple, disons que je crée des classes A et B:Les initialiseurs Objective-C sont-ils autorisés à partager le même nom?
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;
}
Quand je cours, je reçois la sortie suivante:
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 je renverse l'ordre du les importations donc il importe d'abord Bh, je reçois:
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
Pour une raison ou une autre, il semble que l'on utilise le type de données défini dans l'interface @ incluse pour les deux classes. J'ai fait quelques pas à travers le débogueur et j'ai trouvé que le pointeur isa pour les deux objets a et b finit par être le même. J'ai aussi découvert que si je ne fais plus la alloc et init appels en ligne, les deux initialisations semblent fonctionner correctement, par exemple:
A *a = [A alloc];
[a initWithNum:20.0f];
Si j'utilise cette convention lorsque je crée a et b, je reçois le droit la sortie et les pointeurs isa semblent être différents pour chaque objet.
Est-ce que je fais quelque chose de mal? J'aurais pensé que plusieurs classes pourraient avoir les mêmes noms d'initialisation, mais peut-être que ce n'est pas le cas.
Vous pouvez également ajouter statique 'typeWithArgument:' méthodes, comme '[NSNumber numberWithInt:]' à désambiguïser. – drawnonward
Selon la documentation, le 'isa' ivar doit être défini lorsque vous appelez' + [NSObject alloc] '. Puisque les distributions de messages Objective-C sont résolues au moment de l'exécution, n'est-ce pas le travail de l'exécution, pas le travail du compilateur, de déterminer ce à quoi '+ [A alloc]' se résout? –
@Nick Forge: L'implémentation est liée dynamiquement donc ce n'est pas un problème (et cela est vrai ici puisque le NSLog montre A et B comme prévu). Où le compilateur est impliqué dans la construction de l'appel à obj_msgSend. Dans ce cas, un sélecteur utilise un flottant tandis que l'autre utilise un entier, et le compilateur génère des instructions différentes (en stockant l'int dans un registre d'entiers et le flottant dans un registre fp). Pour cette raison, l'implémentation de la méthode trouve des données incorrectes dans le registre attendu. –