【问题标题】:Building a backwards compatible OS X app, when a new API is present?当新的 API 出现时,构建一个向后兼容的 OS X 应用程序?
【发布时间】:2009-09-10 17:35:12
【问题描述】:

我正在尝试升级应用程序 (Clarke) 以提供 10.6 兼容性。

我的计划是根据使用的 OSX 版本使用两种不同的代码路径。

在 10.5 上,它将使用一个控制器,该控制器由完全自定义的代码组成,不依赖于任何特定的 Cocoa API。在 10.6 上,它将使用另一个控制器,它将新的 CoreLocation API 包装在一个相同的接口中,基于相同的抽象类。在运行时,应用将通过检测操作系统版本在控制器之间切换。

这在为 10.6 SDK 构建的 10.6 上运行良好,但相同的构建在 10.5 上会崩溃:

10/09/2009 18:30:50 [0x0-0x12f12f].uk.co.tomtaylor.Clarke[4575] dyld: unknown required load command 0x80000022 
10/09/2009 18:30:51 com.apple.launchd[403] ([0x0-0x12f12f].uk.co.tomtaylor.Clarke[4575]) Exited abnormally: Trace/BPT trap 

如果我为 10.5 SDK 构建,它显然无法编译 CoreLocation 的东西。

我希望能够为此应用程序提供一个二进制文件。有没有办法从 10.5 中“隐藏”CoreLocation API?

【问题讨论】:

    标签: objective-c cocoa xcode macos xcodebuild


    【解决方案1】:

    仅当您在两个平台上具有相同的框架但在较新的平台上有新调用时,部署 SDK 技巧才有效。对于 CoreLocation,10.5 中缺少整个框架,因此您的应用将无法加载,因为它无法动态绑定到框架。

    你需要做以上,加上CoreLocation作为一个弱框架。选择您的链接框架和二进制文件构建阶段,在详细视图中找到 CoreLocation,然后在中间列中将“必需”更改为“弱”。

    当您构建应用时,Xcode 会将 -weak_framework CoreLocation 传递给链接器,并且无论是否存在 CoreLocation,您的应用都会在所有 10.5 和 10.6 系统上加载。不过,除非您实际上是在 10.6 上运行,否则您可以确保不调用任何 CoreLocation 方法。

    【讨论】:

      【解决方案2】:

      您应该能够通过更改目标的构建设置来解决此问题:

      1. 将基础 SDK 设置为 10.6
      2. 将部署 SDK 设置为 10.5

      【讨论】:

      • 这是正确的方法,但还有更多:当您需要调用 10.6 而不是 10.5 中的 API 时,您需要使用 NSClassFromString() 获取类名。然后检查返回的类名是否有效。如果有效,您可以继续调用所需的 API。如果没有,您需要优雅地进行故障转移。
      猜你喜欢
      • 1970-01-01
      • 2011-10-29
      • 2014-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-19
      • 1970-01-01
      相关资源
      最近更新 更多