【问题标题】:Optional Framework Not Working (CoreAudioKit not on Simulator)可选框架不工作(CoreAudioKit 不在模拟器上)
【发布时间】:2015-10-12 23:53:21
【问题描述】:

要让 MIDI 通过蓝牙工作,我需要使用 CoreAudioKit 框架。这完美地工作,但我无法在模拟器上编译。

  1. 使框架“可选”没有帮助,错误是ld: framework not found CoreAudioKit

我认为它应该按照the docs工作

  1. 删除框架允许我的代码编译

我已经在代码中得到了这个,这就是为什么我可以毫无问题地删除框架。

#if !TARGET_IPHONE_SIMULATOR
#import <CoreAudioKit/CoreAudioKit.h>
#endif


我怎样才能让这个可选的编译工作?

【问题讨论】:

    标签: ios ios-simulator coremidi


    【解决方案1】:

    我实际上认为这会起作用,但我认为您可以通过另一种方式解决它。这对我有用:

    1. 删除目标设置中对 CoreAudioKit 的所有引用构建阶段(将二进制文件与库链接)

    2. 确保没有手动输入类似的设置。例如,不要在 Other Linker Flags

      中添加此设置:-weak_framework CoreAudioKit
    3. 使用预处理器标志有条件地为模拟器编译代码:

    #import "ViewController.h"
    
    #if !TARGET_IPHONE_SIMULATOR
    @import CoreAudioKit;
    #endif
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
       [super viewDidLoad];
       // Do any additional setup after loading the view, typically from a nib.
    
    #if !TARGET_IPHONE_SIMULATOR
       if ([CABTMIDICentralViewController class]) {   // maybe not needed?
          CABTMIDICentralViewController *vc = [[CABTMIDICentralViewController alloc] init];
       }
    #endif
    }
    

    注意:在我上面的示例中,您可能不需要测试CABTMIDICentralViewController 类的存在。这取决于您的应用是仅针对 iOS 8+ 还是针对 iOS 7。

    更新

    下面@Yar 和@JeremyHuddlestonSequoia 的每个cmets,请注意,此解决方案需要您在项目构建设置中启用模块自动链接框架。这些 Xcode 设置现在默认为该技术的正确值,但如果您管理的是旧项目,请确保它们已启用。

    其他参考

    https://stackoverflow.com/a/26510640/119114

    https://stackoverflow.com/a/25883210/8047

    【讨论】:

    • 太棒了!这很完美,我认为你不需要CABTMIDICentralViewController 的安全性... 让我感到惊讶的是@import 的使用,并且需要根据这个答案打开它:@987654323 @ 非常感谢您帮助解决此问题。太好了!
    • @Yar,是的,if ([CABTMIDICentralViewController class]) 测试更多用于测试 iOS8 和 iOS7,而不是测试设备和模拟器。
    • 在某些时候,有人必须检查他们是否正在使用UIViewControllernil,但只要我的代码正在编译,我就很高兴看到当前的问题。再次感谢
    • @JeremyHuddlestonSequoia,您有一些有用的信息,但请不要编辑已接受的答案以从根本上改变其含义。如果您愿意,只需添加您自己的新答案。您插入的短语 “解决此问题的方法是使用以 SDK 为条件的链接参数” 与我描述的解决方案 (#1-3) 不匹配,因此它使答案令人困惑和矛盾的。
    • @JeremyHuddlestonSequoia,我完全没有忘记它。我特别建议 ​​not 添加链接参数。我上面显示的代码包括@import CoreAudioKit;。你能解释一下“破坏用户构建目标设备的能力”是什么意思吗?我已经用这个 exact 代码构建了一个 hello world 程序,它肯定是为模拟器或设备构建的。也跑。
    【解决方案2】:

    为了链接某些东西(即使是弱链接),它需要存在于 SDK 中。如果您实际上不使用该框架也没关系;如果指示包含指向它无法找到的文件的链接,链接器将出错。

    您需要根据所使用的 SDK 有条件地编译和链接您的项目。具体来说,当以 iOS SDK 为目标时,您需要包含对 CoreAudioKit.framework 的支持和链接。以 iOS Simulator SDK 为目标时,您将不希望包含此支持或链接。

    要对代码进行条件化,您需要包含标头并使用 TARGET_OS_SIMULATOR 宏(或旧于 iOS 9.0 的 SDK 已弃用的 TARGET_IPHONE_SIMULATOR 宏)。此标头通常通过其他包含拉入,但最好自己这样做。

    例如:

    #import "MyController.h"
    #import <TargetConditionals.h>
    
    #if !TARGET_IPHONE_SIMULATOR
    #import <CoreAudioKit/CoreAudioKit.h>
    #endif
    
    @implementation ViewController
    
    - (void)viewDidLoad {
       [super viewDidLoad];
    
    #if !TARGET_IPHONE_SIMULATOR
       // Stuff dependent on CoreAudioKit
    #endif
    }
    @end
    

    Xcode 在目标的构建阶段不支持 SDK 条件链接,因此请确保在目标的 Link Binary With Libraries 构建阶段中不包含 CoreAudioKit.framework。要处理链接,您基本上有两种选择:

    1. 使用来自 clang 模块的自动链接支持
    2. 使用 SDK 条件链接器标志

    要使用自动链接,您必须将 Xcode 的 Enable Modules(C 和 Objective C)Link Frameworks Automatically 构建设置打开。

    如果您尝试使用较旧的工具链完成类似的操作,或者只是想对链接进行更严格的控制,您仍然可以使用 SDK 条件 Other Linker Flags 构建设置来完成此操作。为此构建设置创建 SDK 条件条目,以便您在默认情况下使用“-framework CoreAudioKit”(或“-weak_framework CoreAudioKit”),而在针对模拟器 SDK 时不使用任何内容。这个屏幕截图应该更清楚。

    如果您的 iOS 部署目标早于 iOS 8,您应该确保对框架进行弱链接,因为它是在 iOS 8 中添加的。如果针对 iOS 8 或更高版本,您可以安全地使用 -framework CoreAudioKit。

    【讨论】:

    • 这里有很多要阅读的内容,所以:与 Nate 的回答相比,这里有什么不同?
    • 我添加了这个答案以提供更多解释,说明您为什么会看到这个问题并解释您的各种选择。 Nate 的回答假定“自动链接框架”已启用,并且我提供了一个附加选项,用于何时未(或不能)启用“自动链接框架”。
    • 谢谢。这很棒。如果你能说得更清楚,我会很高兴。将这个答案分成几个部分(并将这些部分划分)可能会有所帮助。与否,我相信它会对某些人有用。感谢您的帮助。
    • 它已经分为单独的段落。如果您想让它更清晰,那么请务必编辑它:)
    猜你喜欢
    • 2017-07-25
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 2012-08-19
    • 2023-03-23
    • 1970-01-01
    相关资源
    最近更新 更多