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, а в обоих - @implementation раздел для FooClass.

У вас должна быть одна реализация между всеми скомпилированными файлами, но вы можете объявить интерфейс сколько угодно раз, поэтому мы поместили объявление интерфейса в файлы заголовков.

По этой логике, хотя это не соглашение, технически вы можете поместить все в один файл main.m и просто скомпилировать это. Однако для здравого смысла, как только у вас будет больше кода, вы должны разбить его на файлы класса .h/.m.

Существует еще одна (плохая) опция для не использования заголовков, где вы добавляете только раздел @interface к файлам, которые будут включать его, но опять же, я не рекомендую это, потому что вы пройдете через линкерный ад когда вы редактируете одну из этих копий и забываете другую. В вашем случае вы просто добавляете раздел FooClass@interface в начало файла main.m.

+0

Итак, было ли решение разместить код интерфейса в файле Main.m? Я ценю ваше объяснение, но я все еще не понимаю, как избежать использования файлов заголовков. –

+0

Вы могли бы это сделать - я обновил свой ответ, чтобы обсудить это. –

+1

@ Эрик. Избегание файлов заголовков означает наличие только одного файла с именем main.m. Однако, если вы не включаете заголовочные файлы, вы не сможете использовать какие-либо библиотеки/API или организовать свой код. Если у вас несколько исходных файлов, вы должны использовать заголовочные файлы. Если у вас есть один main.m, и все, то вам это не нужно. –

Смежные вопросы