1

我正在尝试动态加载捆绑包,以在少数情况下代替mainBundle使用。我设法用一些资源加载了这个包,比如 Localizable.strings 等等。当我对该包使用本地化StringForKey 时,会加载正确的本地化字符串。这就是说它有效

不过,我什至想获得一个捆绑标识符。因此,我将包含CFBundleIdentifier字符串的info.plist文件添加到 bundle 文件夹的根目录。这,行不通。当我尝试通过

[myBundle bundleIdentifier]

我得到一个空值。我试图将文件都命名为

Info.plist

MyBundle-Info.plist

其中 MyBundle 是包的名称(内容存储在 MyBundle.bundle 中)。但没有运气。

我真的不明白怎么了。我是否必须在 info plist 中设置其他键?或者可能是命名问题?任何帮助将不胜感激。

4

1 回答 1

2

我最终查看了 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目录中,而不是在外面,现在它可以工作了。

我想我在某种程度上是个白痴,因为我完成了所有这些旅行,因为这些东西可能写在文档的某个地方,但我找不到它:(

于 2013-03-26T16:58:31.367 回答