我最终查看了 Core Foundation(毕竟 NSBundle 是基于 CFBundle)源代码,并找出了问题所在。所以..
负责收集 info.plist 内容的函数是CFBundleGetInfoDictionary。每当请求理论上包含在 plist 中的信息时,都会调用此方法。
查看CFBundle.c , CFBundleGetInfoDictionary的实现检查包的 _infoDict 字段是否已初始化,如果未初始化,则对其进行初始化:
if (!bundle->_infoDict) bundle->_infoDict = _CFBundleCopyInfoDictionaryInDirectoryWithVersion(CFGetAllocator(bundle), bundle->_url, bundle->_version);
通过在我的CFBundle上调用该函数,我没有任何运气,所以我猜想在_CFBundleCopyInfoDictionaryInDirectoryWithVersion中一定发生了一些错误。
查看源代码,我注意到,根据 bundle-> _version,使用不同的路径来搜索信息 plist。在这种情况下,版本取决于用于设置捆绑包的目录结构。确切地说,我的版本是0,因为正如函数_CFBundleURLLooksLikeBundleVersion(在包初始化期间使用)中指定的那样,与Resources目录的包是这样的:
// check for existence of "Resources" or "Contents" or "Support Files"
// but check for the most likely one first
// version 0: old-style "Resources" bundles
// version 1: obsolete "Support Files" bundles
// version 2: modern "Contents" bundles
// version 3: none of the above (see below)
// version 4: not a bundle (for main bundle only)
所以,为了结束这个故事,Info.plist 的基本 URL 在_CFBundleCopyInfoDictionaryInDirectoryWithVersion中基于版本 0进行初始化
infoURLFromBase = _CFBundleInfoURLFromBase0;
定义为:
#define _CFBundleInfoURLFromBase0 CFSTR("Resources/Info.plist")
太好了...我已将Info.plist放在Resources目录中,而不是在外面,现在它可以工作了。
我想我在某种程度上是个白痴,因为我完成了所有这些旅行,因为这些东西可能写在文档的某个地方,但我找不到它:(