2010-04-27 7 views
5

동일한 이름의 이니셜 라이저를 사용하지만 다른 형식의 인수를 사용하는 두 개의 클래스가있는 경우 Objective-C에서 이상한 문제가 발생합니다.Objective-C 초기화 프로그램에서 동일한 이름을 공유 할 수 있습니까?

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 : 예를 들어, 내가 클래스 A와 B 만들 가정 해 봅시다

#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; 
} 

내가 이것을 실행하면, 나는 다음과 같은 출력을 얻을 : 나는의 순서를 반대로하면

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 

을 가져 오기 때문에 Bh를 먼저 가져옵니다.

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 

어떤 이유로 든 @interface가 두 클래스 모두에 처음으로 포함되는 데이터 유형을 사용하는 것처럼 보입니다. 나는 디버거를 밟아서 a와 b 객체 모두에 대한 isa 포인터가 끝나는 것을 발견했다. 나는 또한 내가 더 이상 ALLOC하지 않습니다 및 초기화가 인라인 호출하는 경우, 모두 초기화가 제대로 작동하는 것 것을 발견, 예를 들면 : 나는 A와 B 모두를 만들 때이 규칙을 사용하는 경우

A *a = [A alloc]; 
[a initWithNum:20.0f]; 

, 나는 권리를 얻을 출력 및 isa 포인터가 각 개체에 대해 다른 것 같습니다.

내가 잘못 했나요? 여러 클래스가 동일한 초기화 프로그램 이름을 가질 수 있다고 생각 했겠지만 아마도 그렇지 않을 수 있습니다.

답변

5

메서드는 id 형식의 개체를 반환하므로 컴파일러에서 사용할 메서드 서명을 결정할 수 없습니다. 응용 프로그램이 여러 가지 방법으로 올바른 선택기를 선택하게 할 수 있습니다.

A* a = [(A*)[A alloc] initWithNum:20.f]; 
B* b = [(B*)[B alloc] initWithNum:10]; 

아니면 자신이 작업을 수행 할 것입니다하지만 당신은, 당신의 클래스에 ALLOC을 무시하고 뭔가 더 구체적인 반환 할 수 있습니다 : 하나는 그래서, ALLOC의 반환을 캐스팅하는 것입니다. 그래서 :

+ (A*)alloc { return [super alloc]; } 

마지막으로, 나는 개인적으로 선택한 것이 무엇인지, 선택기 더 설명합니다`방법`등 :

// A.h 
- (id)initWithFloat:(float)theNum; 

// B.h 
- (id)initWithInteger:(int)theNum; 
+1

또한 정적'typeWithArgument 추가 할 수 있습니다 [의 NSNumber numberWithInt을 :]'에 불분명하다. – drawnonward

+0

문서에 따르면'+ [NSObject alloc]'을 호출 할 때'isa' ivar가 설정되어야합니다. Objective-C 메시지 디스패치는 런타임에 해결되기 때문에, 컴파일러의 작업이 아니라 런타임의 작업이'+ [A alloc]'이 해결할 작업을 해결할 수 있습니까? –

+0

@Nick Forge : 구현이 동적으로 바운드되므로 문제가되지 않습니다 (NSLog가 A와 B를 예상대로 보여주기 때문에 여기에 해당됩니다). 컴파일러가 관련된 부분은 obj_msgSend에 대한 호출을 작성하는 것입니다. 이 경우 한 선택기는 부동 소수점을 사용하고 다른 소수점은 정수를 사용하고 컴파일러는 다른 명령어를 생성합니다 (int를 정수 레지스터에 저장하고 float을 fp 레지스터에 저장). 이 때문에 메서드를 구현하면 예상되는 레지스터에서 잘못된 데이터가 발견됩니다. –

관련 문제