下面写一个最简单的Demo还原这个情景。
新建一个工程,再新建Hello.h和Hello.c文件,代码如下:
Hello.h
#ifndef __Main__Hello__#define __Main__Hello__#include int main();#endif /* defined(__Main__Hello__) */
Hello.c
#include "Hello.h"int main() { return 0;}
然后在ViewController.m中使用main函数:
#import "ViewController.h"#import "Hello.h"@interface ViewController ()@end@implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; main();}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
编译时具体的报错信息如下:
duplicate symbol _main in: /Users/apple/Library/Developer/Xcode/DerivedData/Main-alxynewqhvyqdafbjcjfzntmqfml/Build/Intermediates/Main.build/Debug-iphonesimulator/Main.build/Objects-normal/i386/Hello.o /Users/apple/Library/Developer/Xcode/DerivedData/Main-alxynewqhvyqdafbjcjfzntmqfml/Build/Intermediates/Main.build/Debug-iphonesimulator/Main.build/Objects-normal/i386/main.old: 1 duplicate symbol for architecture i386clang: error: linker command failed with exit code 1 (use -v to see invocation)
出错原因很明显(因为我的Demo实在太简单了啦):
Hello.c文件中有一个main函数,在编译成Hello.o文件时有一个symbol _main。
而在工程原来的main.m文件中也有一个main函数,在编译成main.o文件时也有一个symbol _main。
而在一个工程中只能有一个main,所以出现了冲突。
解决方法:不要调用C/C++文件中的main函数,或者改写函数名,只是改函数的返回类型或参数列表也是不行的。
以后再遇到duplicate symbol之类的问题,都可以从这个角度出发思考,问题往往出在我们在工程中出现了一些同名的方法或函数,所以导致编译时出现了冲突。而编译时的错误信息A.o和B.o则标识出了这两个重复的symbol出现在哪两个文件中,接着在工程中打开这两个文件搜索冲突的方法名来对比修改。