Iphone 不在Objective-C中使用头文件
我正在创建一个小程序,它由桌面上的几个源文件组成(我没有使用Xcode),我从命令行编译。因为所有的东西都很小,我想跳过使用头文件,把所有的东西都放在我的.m文件中。它会像这样:Iphone 不在Objective-C中使用头文件,iphone,objective-c,compiler-construction,Iphone,Objective C,Compiler Construction,我正在创建一个小程序,它由桌面上的几个源文件组成(我没有使用Xcode),我从命令行编译。因为所有的东西都很小,我想跳过使用头文件,把所有的东西都放在我的.m文件中。它会像这样: Foo.m #import <Foundation/Foundation.h> @interface FooClass : NSObject { } - (void) fooFunction; @end @implementation FooClass - (void) fooFunction
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;
}
Foo.m
#进口
@接口类:NSObject{
}
-(无效)功能;
@结束
@实现类
-(无效)功能{
NSLog(“打印条”);
}
@结束
Main.m
#包括
#导入“fooofunction.m”
int main(int argc,const char*argv[]
{
NSAutoreleasePool*池=[[NSAutoreleasePool alloc]init];
NSLog(@“正在运行…”);
FooFunction*foo=[[FooFunction alloc]init];
[foo-foo函数];
[泳池排水沟];
返回0;
}
当我试图编译这个时,我得到了用于体系结构x86_64的ld duplicate symbol fooofunction blahblahblah
你知道我在这里做错了什么吗?最好包括.m文件(或.c/.cpp)之类的实现文件。如果需要包含一个文件,它可能应该是.h 通过包含Foo.m,就有了链接器不喜欢的两个
FooClass
现有实现。这是因为include类似于此时文件的复制和粘贴
在您的示例中,编译器编译两个文件-main.m和Foo.m,在这两个文件中都有一个@implementation
部分用于FooClass
在所有编译文件之间应该有一个实现,但是可以多次声明接口,这就是我们将接口声明放在头文件中的原因
按照这种逻辑,尽管这不是惯例,但从技术上讲,您可以将所有内容都放在一个main.m文件中,然后进行编译。然而,为了理智起见,一旦有了更多的代码,就应该将其分解为class.h/.m文件
还有一个不使用头的(坏)选项,您只将@interface部分添加到包含它的文件中,但我不建议这样做,因为编辑其中一个副本时,您将经历链接器地狱,而忘记另一个副本。在您的情况下,只需将
FooClass
@interface
部分添加到主.m文件的顶部。最好包含.m文件(或.c/.cpp)之类的实现文件。如果需要包含一个文件,它可能应该是.h
通过包含Foo.m,就有了链接器不喜欢的两个FooClass
现有实现。这是因为include类似于此时文件的复制和粘贴
在您的示例中,编译器编译两个文件-main.m和Foo.m,在这两个文件中都有一个@implementation
部分用于FooClass
在所有编译文件之间应该有一个实现,但是可以多次声明接口,这就是我们将接口声明放在头文件中的原因
按照这种逻辑,尽管这不是惯例,但从技术上讲,您可以将所有内容都放在一个main.m文件中,然后进行编译。然而,为了理智起见,一旦有了更多的代码,就应该将其分解为class.h/.m文件
还有一个不使用头的(坏)选项,您只将@interface部分添加到包含它的文件中,但我不建议这样做,因为编辑其中一个副本时,您将经历链接器地狱,而忘记另一个副本。在您的情况下,只需将
FooClass
@interface
部分添加到main.m文件的顶部。那么解决方案是将接口代码放在main.m文件中吗?感谢您的解释,但我仍然不清楚如何避免使用头文件。@Eric:避免头文件意味着只有一个名为main.m的文件。但是,如果不包含任何头文件,则将无法使用任何库/API或组织代码。如果有多个源文件,则应使用头文件。如果你有一个main.m,就这样了,那么你就不必了。我还添加了一个我忘记了,几乎不想提及的案例,因为这是一个黑客攻击,但是可以处理多个.m文件而不需要.h文件。那么解决方案是将接口代码放在main.m文件中吗?感谢您的解释,但我仍然不清楚如何避免使用头文件。@Eric:避免头文件意味着只有一个名为main.m的文件。但是,如果不包含任何头文件,则将无法使用任何库/API或组织代码。如果有多个源文件,则应使用头文件。如果您有一个main.m,仅此而已,那么您就不必了。我还添加了一个案例,我忘记了,几乎不想提及,因为这是一个黑客攻击,但可以处理多个.m文件,而不需要.h文件。