Не использовать заголовочные файлы в Objective-C - PullRequest
1 голос
/ 11 февраля 2012

Я создаю небольшую программу, которая состоит из нескольких исходных файлов на моем рабочем столе (я не использую XCode), которые я компилирую из командной строки.Так как все очень маленькое и маленькое, я хотел бы пропустить использование заголовочных файлов и иметь все в моем .m файле.Хотелось бы что-то вроде этого:

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

Любые идеи о том, что я делаю здесь неправильно?

1 Ответ

4 голосов
/ 11 февраля 2012

Не рекомендуется включать файлы реализации, такие как файлы .m (или .c / .cpp). Если вам нужно включить файл, он, вероятно, должен быть .h.

Включая Foo.m, у вас есть две реализации FooClass, которые не нравятся компоновщику. Это связано с тем, что включение в этот момент похоже на копирование и вставку файла.

В вашем примере компилятор компилирует два файла - main.m и Foo.m, и в обоих есть раздел @implementation для FooClass.

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...