当存在新的API时,构建向后兼容的OS X应用程序?

tom*_*lor 8 macos xcode cocoa objective-c xcodebuild

我正在尝试升级应用程序(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 
Run Code Online (Sandbox Code Playgroud)

如果我构建10.5 SDK,显然无法编译CoreLocation.

我希望能够为这个应用程序提供单个二进制文件.有没有办法从10.5中"隐藏"CoreLocation API?

cde*_*osa 5

部署SDK技巧仅在两个平台上具有相同框架但在较新平台上具有新呼叫时才起作用.对于CoreLocation,整个框架在10.5上缺失,因此您的应用程序将无法加载,因为它无法动态绑定到框架.

您需要执行上述操作,并将CoreLocation添加为弱框架.选择Link Frameworks和Binaries构建阶段,在Detail视图中找到CoreLocation,在中间列中将"Required"更改为"Weak".

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


Mar*_*fer 4

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

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

  • 这是正确的方法,但还有更多内容:当您需要调用 10.6 中但不是 10.5 中的 API 时,您需要使用 NSClassFromString() 获取类名。然后检查返回的类名是否有效。如果有效,您可以继续调用您需要的 API。如果没有,您将需要优雅地进行故障转移。 (4认同)