14

UITableView像s, s 这样的元素UINavigationBar在 iOS 7 上有不同的风格。

这种风格是在运行时确定的,因为这些类是在 上实现的UIKit,并且UIKit在运行时与您的应用程序动态链接,而不是在编译时静态链接。

因此,人们会认为任何在 iOS 7 上运行的应用程序都会使这些元素看起来与在 iOS 7 上的外观相同。但是,在您使用 iOS 7 SDK 编译之前,它们会保持与过去在 iOS 6 上相同的风格。除了其中一些(如UIAlertViewUIMenuController

我对此的唯一解释是他们做了类似这样的事情:

#define SDKApplicationWasLinkedAgainst ...
if (SDKApplicationWasLinkedAgainst < 7.0)
    ...
else
    ...

这显然真的很麻烦,因为他们需要继续维护很多旧代码。所以我很好奇,这真的是引擎盖下发生的事情吗?我错过了什么?

4

3 回答 3

9

在不涉及 NDA 领域的情况下,我只想说是的,他们根据以下调用的结果来限制外观和行为:

_UIApplicationUsesLegacyUI()

反过来,这个函数会调用GSApplicationUsesLegacyUI(),我认为它会根据链接的 UIKit 的版本返回一个结果。

这意味着是的,他们正在为遗留的 UIKit 部分设置条件。不确定这是一件好事,但这就是他们决定做的事情。

于 2013-08-13T22:18:11.233 回答
4

我敢打赌,他们使用框架兼容版本

每次编译您的应用程序时,您的应用程序都会链接到特定框架,包括兼容性版本和当前版本。如果您运行,您可以看到这些数字otool -L YourApp.app/YourApp。例如,对于前段时间编译的应用程序,我得到了这个:

/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 751.58.0)
/System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 1500.0.0)

如您所见,UIKit 框架的完整路径存储在 Mach-O 二进制文件中,以及几个版本(特别是我当时编译的版本)。

我想 iOS 7 将包含两个 UIKit 版本:iOS6 中标有相应版本并表示从 1.0.0 开始兼容的版本,以及 iOS7 中标有与高于 1500.0.0 的版本兼容的版本(我不知道如果这是 iOS 6.1.3 的数字,但你明白了)。

当你的 iOS6 二进制文件被加载时,它的库依赖被读取dyld并解析,因为你编译时说current version 1500.0.0,并且 iOS 7 的库说compatibility version 1501.0.0,你将链接到 iOS 6 的库。

由于框架也是一个捆绑包,所有资源都被完美地包含,并且只会被正确的版本使用,这就是如果您针对 iOS 6 SDK 或 iOS 7 SDK 进行编译时不同的视觉元素看起来会有所不同。

我可能是错的,但我只是希望他们没有使用您建议的代码技术,因为那将是一个糟糕的代码库来维护。

于 2013-07-10T19:40:12.313 回答
-1

我不能确定,但​​这是关于它是如何完成的一个猜测。因为他们知道您的应用程序所链接的 SDK 版本,所以他们在 iOS 7 设备上对框架进行了版本化。所以文件系统上有一个层次结构/.../iPhoneOS6.1.sdk/.../Frameworks/UIKit。然后,当它加载您的应用程序时,他们只需将库的搜索路径设置为指向您的应用程序链接的任何 SDK。

这就是 Xcode 现在的做法。在 Xcode 包内的 Developer 目录中是一个 SDKs 目录,该目录又包含要链接的所有不同的 SDK。

于 2013-07-10T19:04:46.090 回答