2012-02-11 2 views
1

저는 명령 줄에서 컴파일 한 (Xcode를 사용하지 않고 있습니다) 바탕 화면에 몇 개의 소스 파일로 구성된 작은 프로그램을 만들고 있습니다. 모든 것이 아주 작고 작기 때문에 헤더 파일을 사용하지 않고 내 .m 파일에있는 모든 것을 가지고 싶습니다. 그것은 이런 식으로 뭔가를 싶습니다Objective-C에서 헤더 파일을 사용하지 않습니다.

Foo.m 

#import <Foundation/Foundation.h> 

@interface FooClass : NSObject { 
} 
- (void) fooFunction; 

@end 


@implementation FooClass 

- (void) fooFunction { 

    NSLog(@"Printing bar"); 

} 

@end 




Main.m 

#include <stdlib.h> 
#import "FooFunction.m" 


int main (int argc, const char *argv[]) 
{ 

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
    NSLog (@"Running...."); 

    FooFunction *foo = [[FooFunction alloc] init]; 
    [foo fooFunction]; 

    [pool drain]; 
    return 0; 

} 

내가 잘못 여기서 뭘하는지 나는 내가 ld duplicate symbol fooFunction blahblahblah for architecture x86_64

의 어떤 아이디어를 얻을이를 컴파일하려고?

답변

4

.m 파일 (또는 .c/.cpp)과 같은 구현 파일을 포함시키는 것은 좋지 않습니다. 파일을 포함해야하는 경우 아마 .h 여야합니다.

Foo.m을 포함하면 링커가 원하지 않는 FooClass이라는 두 가지 구현이 있습니다. 이것은 include가 그 시점에서 파일의 복사 및 붙여 넣기와 유사하기 때문입니다.

예에서 컴파일러는 main.m과 Foo.m의 두 파일을 컴파일하며 두 파일 모두에 FooClass에 대한 @implementation 섹션이 있습니다.

모든 컴파일 된 파일간에 하나의 구현이 있어야하지만 인터페이스 선언을 여러 번 선언 할 수 있습니다. 이는 헤더 파일에 인터페이스 선언을 지정하는 이유입니다.

이 논리에 따르면, 관례는 아니지만 기술적으로는 모든 것을 하나의 main.m 파일에 넣고 컴파일하면됩니다. 그러나 일단 코드가 생기면 클래스 .h/.m 파일로 분리해야합니다.

@interface 섹션을 포함 할 파일에만 헤더를 사용하지 않는 또 다른 옵션이 있습니다.하지만이 옵션은 링커 지옥을 통과하기 때문에 권장하지 않습니다. 이 사본 중 하나를 편집하고 다른 사본을 잊어 버릴 때. 귀하의 경우에는 FooClass@interface 섹션을 main.m 파일의 맨 위에 추가하기 만하면됩니다.

+0

그렇다면 인터페이스 코드를 Main.m 파일에 저장하는 것이 해결책일까요? 귀하의 설명을 주셔서 감사하지만 헤더 파일 사용을 피하는 방법은 아직 명확하지 않습니다. –

+0

당신은 그것을 할 수 있습니다 - 나는 이것을 논의하기 위해 나의 대답을 업데이트했습니다. –

+1

@Eric : 헤더 파일을 피하는 것은 main.m이라는 파일 하나만 갖는 것을 의미합니다. 그러나 헤더 파일을 포함하지 않으면 라이브러리/API를 사용하거나 코드를 구성 할 수 없습니다. 소스 파일이 여러 개인 경우 헤더 파일을 사용해야합니다. main.m이 하나 뿐이라면 그럴 필요가 없습니다. –

관련 문제