【问题标题】:Linker "Duplicate Symbol" error due to circular reference由于循环引用,链接器“重复符号”错误
【发布时间】:2017-03-29 14:30:43
【问题描述】:

我有一个类的两个标题和它的扩展名(由 Xcode 为 NSManaged 对象生成)。但是我收到了一个链接器错误,我发现这是由于循环引用造成的。

对话+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 声明并删除标题。所以我注释掉了Conversation+CoreDataProperties.h中的import语句,并添加了@class Conversation;。现在弹出两个错误,说它是一个未定义的类。附上以下错误的屏幕截图。我不太明白为什么会发生这种情况以及我需要做些什么来解决它。任何帮助深表感谢。谢谢!

链接器错误

重复符号 _OBJC_CLASS__$_Conversation 在: /Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/Conversation+CoreDataClass.o 重复符号 _OBJC_METACLASS_$_Conversation 在: /Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/Conversation+CoreDataClass.o 重复符号 _OBJC_CLASS_$_ConversationDate 在: /Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/ConversationDate+CoreDataClass.o 重复符号 _OBJC_METACLASS_$_ConversationDate 在: /Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/ConversationDate+CoreDataClass.o ld:架构arm64 clang的4个重复符号:错误:链接器 命令失败,退出代码为 1(使用 -v 查看调用)

【问题讨论】:

  • 这有点奇怪。尝试清理您的项目(shift-cmd-K)并重建。
  • @dirkgroten 这没有帮助。仍然有错误。

标签: ios objective-c circular-reference


【解决方案1】:

所以我把Conversation+CoreDataProperties.h中的import语句注释掉,加上@class Conversation;。

只有在不使用任何Convention 类的接口时才能这样做(例如声明Convention 类型的属性。如果你正在扩展Convention,则不能这样做通过类别或类扩展。

您必须在此处解决合法的循环引用。您可以:

  1. 将类和类别移动到同一个源文件中(如果没有特殊原因需要将其放在一个类别中,您可以将 fetchRequest 的声明移动到类本身中)。
  2. 停止在类头中导入+CoreDataProperties.h,而是在调用者需要调用fetchRequest的地方导入它。

【讨论】:

  • 进行更改使其编译,但我仍然收到重复符号的链接器错误。我在问题中添加了错误
【解决方案2】:

出现重复符号警告是因为

  1. 您的项目中有多次该类,编译器不知道该选择哪个(那么它主要是重复链接错误)
  2. 您的 ConversationDate+CoreDataClass 有问题

只是从源代码中提出的一个问题:为什么要导入要扩展的类的扩展?

#import "Conversation+CoreDataClass.h"
@interface Conversation (CoreDataProperties)

+ (NSFetchRequest<Conversation *> *)fetchRequest;

@end

所有扩展类通常需要知道的基本上是它们扩展的类:

#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

最后一个问题:您确定您的项目中不存在其他同名的类扩展吗? CoreData 也可能自己创建了它们。

请查看您的 xCode 项目,如下所示:

【讨论】:

  • 我找到了问题的解决方案,发布了答案。此外,没有任何重复的文件存在。对于why do you import an extension of the class you want to extend? 的问题,这是由 Xcode 自动生成的 :) 尽管删除 import 语句或将扩展代码直接移动到类中似乎并没有帮助我解决这个问题。
  • 酷!不要忘记将您自己的答案标记为解决方案,以便可以关闭线程:)
  • 我只能在一天后将其标记为已回答。明天会做:)
【解决方案3】:

answer 中找到了我的问题的解决方案。我只需要从编译源中删除 .m 文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-10
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 2014-01-16
    • 1970-01-01
    相关资源
    最近更新 更多