由于循环引用导致链接器 "Duplicate Symbol" 错误
Linker "Duplicate Symbol" error due to circular reference
我有两个 header 的 class 和它的扩展名(由 Xcode 为 NSManaged object 生成)。但是我收到链接器错误,我发现这是由于循环引用造成的。
对话+CoreDataClass.h
NS_ASSUME_NONNULL_BEGIN
@interface Conversation : NSManagedObject
@end
NS_ASSUME_NONNULL_END
#import "Conversation+CoreDataProperties.h"
对话+CoreDataProperties.h
#import "Conversation+CoreDataClass.h"
NS_ASSUME_NONNULL_BEGIN
@interface Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest;
@end
NS_ASSUME_NONNULL_END
你可以清楚地看到这里的循环引用。我发现此 question 问题在于添加 @class
声明并删除 header。所以我把Conversation+CoreDataProperties.h
里的import
语句注释掉,加上@class Conversation;
。现在弹出两个错误,说它是未定义的 class。已附上以下错误的屏幕截图。我不太明白为什么会发生这种情况以及我需要做些什么来解决它。任何帮助深表感谢。谢谢!
链接器错误
duplicate symbol _OBJC_CLASS_$_Conversation in:
/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/Conversation+CoreDataClass.o
duplicate symbol _OBJC_METACLASS_$_Conversation in:
/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/Conversation+CoreDataClass.o
duplicate symbol _OBJC_CLASS_$_ConversationDate in:
/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/ConversationDate+CoreDataClass.o
duplicate symbol _OBJC_METACLASS_$_ConversationDate in:
/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/ConversationDate+CoreDataClass.o
ld: 4 duplicate symbols for architecture arm64 clang: error: linker
command failed with exit code 1 (use -v to see invocation)
So I commented out the import statement in the Conversation+CoreDataProperties.h and added @class Conversation;.
如果您没有使用任何 Convention
class 的接口(例如声明 属性 类型 Convention
。如果您通过类别或 class 扩展名扩展 Convention
,则无法执行此操作。
你这里有一个合法的循环引用你必须解决。您可以:
- 将 class 和类别移动到同一个源文件中(如果没有特殊原因需要将其放在类别中,您可以将
fetchRequest
的声明移动到 class本身)。
- 停止在 class header 中导入
+CoreDataProperties.h
,而是在调用者需要调用 fetchRequest
. 的任何地方导入它
重复符号警告的结果是因为
- 你的项目中有多次class,编译器不知道该选择哪个(那么多半是重复链接错误)
- 你的ConversationDate+CoreDataClass
有问题
只是从您的源代码中提出的一个问题:为什么要导入要扩展的 class 的扩展?
#import "Conversation+CoreDataClass.h"
@interface Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest;
@end
所有扩展 class 通常需要知道的基本上是它们扩展的 classes:
#import "Conversation.h"
@interface Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest;
@end
只有实现文件 (.m) 需要导入头文件。例如:
#import "Conversation+CoreDataClass.h"
@implementation Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest {
// body
return nil;
}
@end
最后一个问题:您确定您的项目中不存在其他 class 同名扩展吗? CoreData 也可能自己创建了它们。
请像这样查看您的 xCode 项目:
在此 answer 中找到了解决我的问题的方法。我只需要从 Compile Sources 中删除 .m 文件。
我有两个 header 的 class 和它的扩展名(由 Xcode 为 NSManaged object 生成)。但是我收到链接器错误,我发现这是由于循环引用造成的。
对话+CoreDataClass.h
NS_ASSUME_NONNULL_BEGIN
@interface Conversation : NSManagedObject
@end
NS_ASSUME_NONNULL_END
#import "Conversation+CoreDataProperties.h"
对话+CoreDataProperties.h
#import "Conversation+CoreDataClass.h"
NS_ASSUME_NONNULL_BEGIN
@interface Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest;
@end
NS_ASSUME_NONNULL_END
你可以清楚地看到这里的循环引用。我发现此 question 问题在于添加 @class
声明并删除 header。所以我把Conversation+CoreDataProperties.h
里的import
语句注释掉,加上@class Conversation;
。现在弹出两个错误,说它是未定义的 class。已附上以下错误的屏幕截图。我不太明白为什么会发生这种情况以及我需要做些什么来解决它。任何帮助深表感谢。谢谢!
链接器错误
duplicate symbol _OBJC_CLASS_$_Conversation in: /Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/Conversation+CoreDataClass.o duplicate symbol _OBJC_METACLASS_$_Conversation in: /Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/Conversation+CoreDataClass.o duplicate symbol _OBJC_CLASS_$_ConversationDate in: /Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/ConversationDate+CoreDataClass.o duplicate symbol _OBJC_METACLASS_$_ConversationDate in: /Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/ConversationDate+CoreDataClass.o ld: 4 duplicate symbols for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
So I commented out the import statement in the Conversation+CoreDataProperties.h and added @class Conversation;.
如果您没有使用任何 Convention
class 的接口(例如声明 属性 类型 Convention
。如果您通过类别或 class 扩展名扩展 Convention
,则无法执行此操作。
你这里有一个合法的循环引用你必须解决。您可以:
- 将 class 和类别移动到同一个源文件中(如果没有特殊原因需要将其放在类别中,您可以将
fetchRequest
的声明移动到 class本身)。 - 停止在 class header 中导入
+CoreDataProperties.h
,而是在调用者需要调用fetchRequest
. 的任何地方导入它
重复符号警告的结果是因为
- 你的项目中有多次class,编译器不知道该选择哪个(那么多半是重复链接错误)
- 你的ConversationDate+CoreDataClass 有问题
只是从您的源代码中提出的一个问题:为什么要导入要扩展的 class 的扩展?
#import "Conversation+CoreDataClass.h"
@interface Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest;
@end
所有扩展 class 通常需要知道的基本上是它们扩展的 classes:
#import "Conversation.h"
@interface Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest;
@end
只有实现文件 (.m) 需要导入头文件。例如:
#import "Conversation+CoreDataClass.h"
@implementation Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest {
// body
return nil;
}
@end
最后一个问题:您确定您的项目中不存在其他 class 同名扩展吗? CoreData 也可能自己创建了它们。
请像这样查看您的 xCode 项目:
在此 answer 中找到了解决我的问题的方法。我只需要从 Compile Sources 中删除 .m 文件。