我有一个班级结构
Class A
{
Object of classB
Object of classC
}
现在为此我有文件A.h / A.m B.h / B.m,C.h / C.m. 现在我有一个单独的文件G.h,它有许多全局变量,所有的变量都由A,B,C类使用 现在我在A.h里面导入了B.h,C.h,G.h。我还在B.h和C.h
中单独导入了文件G.h.现在,在构建项目时,我在全局变量上收到重复符号的链接错误(这可能是由于多次包含文件G.h)。
我该如何解决这个问题?以下是我的代码结构
//A.h
#import "B.h"
#import "C.h"
#import "G.h"
@interface A : NSObject {
B *b;
C *c;
}
//B.h
#import "G.h"
//C.h
#import "G.h"
//G.h
A *a=nil;
@interface G : NSObject { //whole class is empty}
答案 0 :(得分:3)
你应该在G.h
中声明你的全局变量,但在G.m
中定义它们,以便它们只在目标中链接一次。因此,例如,如果你有一个全局定义的字符串常量,你可以这样做:
<强> G.h
强>
extern NSString const *appName;
<强> G.m
强>
NSString const *appName = @"My Great App";
在粘贴的代码中,它是被复制的A
实例。它被导入到彼此的翻译单元中,但每次都使用相同的名称,这意味着编译的对象无法链接。假设您想要一个名为A
的共享a
实例,您可以执行以下操作:
<强> G.h
强>
@class A;
extern A *a;
<强> G.m
强>
#import "A.h"
#import "G.h"
A *a = nil;
答案 1 :(得分:0)
在类标题中使用@class
编译器指令,而不是导入其他类的标头。 @class
提供给定类的前向声明,因此您可以推迟导入其标头,直到您真正需要它为止,这通常位于相应的.m
文件中。
所以不要这样:
#import "B.h"
@interface A : NSObject
{
B someObj;
}
......做这个
@class B;
@interface A : NSObject
{
B someObj;
}
现在编译器将理解B
是类的名称,因此允许您将其用作数据类型而不导入B
的标头。