使用GoogleCast.framework重复出现符号错误

时间:2015-04-24 19:14:06

标签: ios objective-c xcode google-cast mach-o

我刚刚开始将Android应用程序移植到iOS,并且遇到了一个很大的障碍,尽管我在搜索许多类似的问题时仍然无法弄清楚。

我正在尝试遵循CastVideos sample中实现的模式,其中GoogleCast API封装在我称为CastManager的单例类中。要使用我的单例类,我在AppDelegate.m中#import "CastManager.h"。然后在CastManager.h中,我#import <GoogleCast/GoogleCast.h>以便我可以使用它的类和协议作为CastManager的公共接口的一部分。但是,因为我在CastManager.m和AppDelegate.m中导入CastManager.h,所以链接器正在从GoogleCast框架中找到重复的符号。

这是我的CastManager.h:

#import <GoogleCast/GoogleCast.h>
#import <Foundation/Foundation.h>

@interface CastManager : NSObject

@property(nonatomic, strong) GCKDeviceScanner *deviceScanner;

+ (instancetype)sharedCastManager;

@end

相应的CastManager.m:

#import "CastManager.h"

@implementation CastManager

+ (instancetype)sharedCastManager {
    NSLog(@"sharedCastManager");
    static CastManager *singleton = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        singleton = [[self alloc] init];
    });
    return singleton;
}

- (instancetype)init {
    NSLog(@"init()");
    if (self = [super init]) {
        self.deviceScanner = [[GCKDeviceScanner alloc] init];
    }
    return self;
}

@end

这是我的AppDelegate.m的主要部分:

#import "AppDelegate.h"
#import "CastManager.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    CastManager *castManager = [CastManager sharedCastManager];
    return YES;
}

但是,这会在尝试构建项目时导致链接器出现以下错误:

duplicate symbol _kGCKDeviceCapabilityVideoOut in:
    /Users/nate/Library/Developer/Xcode/DerivedData/MyCastApp-ezrgxdnlvywpanerezulnarzknno/Build/Intermediates/MyCastApp.build/Debug-iphonesimulator/MyCastApp.build/Objects-normal/x86_64/AppDelegate.o
    /Users/nate/Library/Developer/Xcode/DerivedData/MyCastApp-ezrgxdnlvywpanerezulnarzknno/Build/Intermediates/MyCastApp.build/Debug-iphonesimulator/MyCastApp.build/Objects-normal/x86_64/CastManager.o
... many similar errors ommitted for brevity ...
duplicate symbol _kGCKDeviceCapabilityAudioIn in:
    /Users/nate/Library/Developer/Xcode/DerivedData/MyCastApp-ezrgxdnlvywpanerezulnarzknno/Build/Intermediates/MyCastApp.build/Debug-iphonesimulator/MyCastApp.build/Objects-normal/x86_64/AppDelegate.o
    /Users/nate/Projects/MyCastApp/GoogleCast.framework/GoogleCast(GCKDevice.o)
ld: 8 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

据我所知,这完全复制了CastVideos示例中定义的模式,但是样本编译得很好,而我的编译没有,我已经仔细研究了两个项目,试图找到不同的东西,但是我只是没有看到它。此外,我没有看到这样做有什么问题,并期望它能正常工作。我真想不出其他任何办法。

以下是CastVideos示例中的相关文件以供比较:

其他问题指向不适用或不解决的解决方案:

  • 我没有意外导入.m文件。
  • 我没有对项目中任何文件的重复引用。
  • “构建阶段”项目设置的“编译源”部分不包含任何重复项。
  • 我已经添加了'-ObjC'链接器标记,如GoogleCast API文档所述,但无论是否有相同的错误。
  • 我尝试删除代理数据并在构建之前进行清理。
  • 这是在OS X Yosemite 10.10.3上运行的Xcode 6.3.1和来自the SDK documentation page
  • 的GoogleCastSDK-2.6.0软件包

我已在https://github.com/nshafer/MyCastApp

中检查了我的示例项目中的问题

非常感谢任何帮助!

编辑:副本有点相关,它肯定是相同的符号,但那里的答案没有帮助,因为我没有使用Object-C ++,而只是Objective-C。我没有.mm文件,只有.m文件。

3 个答案:

答案 0 :(得分:7)

对我来说,它有助于将“No Common Blocks”编译器设置切换为NO:

enter image description here

这似乎很有意义,这里解释了设置:What is GCC_NO_COMMON_BLOCKS used for?

答案 1 :(得分:0)

链接器告诉您在两个文件AppDelegate.m和CastManager.m中有一个名为kGCKDeviceCapabilityVideoOut的变量。由于它不在您的源代码中,因此您最有可能使用GoogleCast代码。

更改GoogleCast.h文件,或确保它仅包含在一个.m文件中。从CastManager.h中包含它意味着它间接包含在包含CastManager.h的每个文件中,所以我会避免这种情况并且只包含它来自CastManager.m。您可能需要添加

@class GCKDeviceScanner;
在您的CastManager.h文件中

答案 2 :(得分:0)

我找到了另一个修复,即在GoogleCast.framework / Headers文件夹中编辑GCKDevice.h。将4个常量从GCK_EXPORT更改为文件顶部附近的GCK_EXTERN

/** Device capability flag for video out. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityVideoOut;
/** Device capability flag for video in. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityVideoIn;
/** Device capability flag for audio out. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityAudioOut;
/** Device capability flag for audio in. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityAudioIn;

我在bug report我向谷歌的问题跟踪器提交了详细信息,但它被标记为另一个有些相关问题的副本。无论哪种方式,它可能会在下一个版本中修复。在此之前,我建议改变Joobik'com的答案中详述的“No Common Blocks”设置,因为这不涉及更改第三方代码。