否 "kCFBundleVersionKey" 有时:所有可能的情况?

No "kCFBundleVersionKey" sometimes: all possible scenarios?

我的应用程序中有这样的代码:

NSString* version = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];

在大多数情况下它有效,returns Bundle version,但有时(假设在 2% 的情况下)它 returns nil.

代码在函数[AppDelegate application:didFinishLaunchingWithOptions:]中调用,在主线程中,一个应用程序在前台。

我可以想象这是一个 Apple 的错误,有一些文件读取错误,但作为一个罕见的 Apple 错误,百分比相当高。 我也知道一个人可能会搞砸 versions/bundles/Info.plist - 但这个百分比对于这种情况来说太小了。

那么,第一个问题:在这种情况下,[[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey]返回nil的原因是什么?

第二个问题:你知道这些假设是否有意义/是否容易验证:

  1. 用户在更新后首次启动应用程序,[NSBundle mainBundle]application:didFinishLaunchingWithOptions之后配置完全application:didFinishLaunchingWithOptions?
  2. 应用程序正在自动更新(从 AppStore),用户打开它,系统正在正在写入新数据到Info.plist.
  3. 我应用中的某些后台线程也在读取 [NSBundle mainBundle],系统使用了一些奇怪的锁,因此从主线程读取失败。

UPD:我看过 this question,但没有关系。

默认情况下,应用程序的所有文件在使用内容保护的设备上都是加密的。如果您尝试在它们被解密(由 OS)之前阅读它们,您将得到 nil。文件已解密,并且在用户解锁 phone 后 不久 可用,如果您为 data protection entitlement. So the data might not be available when the application launches because they are not yet decrypted. This might be one reason that you get nil some times, the solution would be to wait to be notified in the app delegate 设置不同的值,这可能会改变并且更加严格在您阅读它们之前,它们的数据已准备就绪。

第二题所有部分的答案都是NO。在可能影响主 Bundle 的更新后,应用程序不需要执行任何记录的配置。用户无法打开正在更新的应用程序。对主 Bundle 的访问是线程安全的。