Ich bin auf ein seltsames Problem in Objective-C, wenn ich zwei Klassen mit Initializern mit dem gleichen Namen, aber anders getippten Argumente. Zum Beispiel, sagen wir, ich Klassen A und B erstellen:Können Objective-C-Initialisierer den gleichen Namen verwenden?
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;
}
Als ich dies ausführen, bekomme ich die folgende Ausgabe:
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
Wenn ich die Reihenfolge der reversen Importe, so importiert es Bh zuerst, ich bekomme:
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
Aus irgendeinem Grund scheint es, als ob es den Datentyp verwendet, der in jedem Interface definiert ist, das für beide Klassen zuerst eingefügt wird. Ich habe ein paar Schritte durch den Debugger gemacht und festgestellt, dass der isa-Zeiger für a- und b-Objekte identisch ist. Ich fand auch heraus, dass, wenn ich nicht mehr die alloc machen und init ruft inline, beide Initialisierungen scheinen richtig zu arbeiten, zum Beispiel:
A *a = [A alloc];
[a initWithNum:20.0f];
Wenn ich diese Konvention verwenden, wenn ich a und b erstellen, erhalte ich das Recht Ausgabe und die isa Zeiger scheinen für jedes Objekt unterschiedlich zu sein.
Mache ich etwas falsch? Ich hätte gedacht, dass mehrere Klassen die gleichen Initialisierungsnamen haben könnten, aber das ist vielleicht nicht der Fall.
Sie können auch statische 'typeWithArgument hinzu:' Methoden, wie '[NSNumber numberWithInt:]' zu disambiguate. – drawnonward
Laut der Dokumentation sollte der 'isa'-Ivar gesetzt werden, wenn Sie' + [NSObject alloc] 'aufrufen. Da Objective-C-Nachrichtenmeldungen zur Laufzeit aufgelöst werden, ist es nicht der Job der Laufzeit, nicht der Job des Compilers, um herauszufinden, was '+ [A alloc]' verrechnet? –
@Nick Forge: Die Implementierung ist dynamisch gebunden, so dass dies kein Problem ist (und dies gilt auch hier, da der NSLog A und B wie erwartet anzeigt). Wenn der Compiler beteiligt ist, baut er den Aufruf von obj_msgSend auf. In diesem Fall verwendet ein Selektor einen Fließkommawert, während der andere eine Ganzzahl verwendet, und der Compiler erzeugt verschiedene Anweisungen (speichert das int in einem Ganzzahlregister und das Gleitkomma in einem fp-Register). Aus diesem Grund findet die Implementierung der Methode fehlerhafte Daten, wenn sie im erwarteten Register aussieht. –