最近看苹果文档《Bundle Programming Guide》,发现其中就NSBundle定位资源的搜索模式前后描述不一致。
P31, "localized resources in bundles"中提到
When looking for resources in your bundle, the bundle-loading code looks first in any region-specific directories, followed by the language-specific directory. And if neither localized directory contains the resource, the bundle-loading code looks for an appropriate nonlocalized resource.
在bundle中搜索资源时,相关代码会首先搜索特定地区目录,然后搜索特定语言目录。如果上述两个地方都没有找到相应的资源,那么会在寻找非本地话资源。
个人对以上的搜索顺序理解为:region.lproj目录--->language.lproj目录--->根目录
但是,还是这份文档P38 "The Bundle Search Pattern"中又提到:
Then the bundle searches for the resource in the following order:
Global (nonlocalized) resources
Region-specific localized resources (based on the user’s >region preferences)
Language-specific localized resources (based on the user’s language preferences)
Development language resources (as specified by the CFBundleDevelopmentRegion in the bundle’s Info.plist file.)
在bundle中寻找特定资源的顺序如下:1.非本地化资源中 2.地区目录 3.语言目录 4.开发语言目录
按照这段话,搜索的顺序变成了:根目录--->region.lproj目录--->language.lproj目录
自相矛盾的不止这一处。P16 "Anatomy of an iOS Application Bundle"中又提到:
Even if you provide localized versions, however, you should always include a default version of these files at the top-level of your application bundle. The default version is used in situations where a specific localization is not available.
即使对某些资源进行了本地化,依然要在根目录下放一个默认版本的文件,以防没有针对某些语言或地区进行本地化。
可以,在P38 "The Bundle Search Pattern"中,给出了完全相反的叙述:
Because global resources take precedence over language-specific resources, there should never be both a global and localized version of a given resource. If a global version of a resource exists, language-specific versions of the same resource are never returned.
由于非本地化资源(这里的global就是non-localized,文档中有说明)的优先级高于本地化资源,同一个资源绝对不要同时出现一个本地化版本和一个非本地化版本。如果这样的话,本地化的版本永远不会被获取。
请问是我傻逼了还是苹果傻逼了。这文档就没人看吗?2015年6月更新的文档。
大体没错,算指代不清,第一段描述确实是错了。。。Bundle 的搜索顺序是:
先在根目录找(global resources/nonlocalized resources)
根目录找不到就去用户对应地区文件(中文中国,中文台湾)夹找
然后语言文件夹(中文)
都没有就 fallback 到 Localization native development region (以下简称 DR)指定的文件夹找(默认是 en,项目设置里改)
都找不到就瞎。
放资源的原则
根目录放所有语言共用的东西,不管什么地区语言,都用同一个。
然后 DR 文件夹里放所有需要本地化的东西,任何没有做本地化处理的语言、地区都会 fallback 到这里。
各种语言的文件夹要有和 DR 中一样的一套资源。当然内容是各个语言本地化之后的。
可以看到按照这个原则来排布本地化资源,按前面的搜索顺序去搜索的话是不会出现冲突的。
你提到的:
依然要在根目录下放一个默认版本的文件
可以理解为根目录下面默认版本的 DR 本地化文件夹(没改的话就是 en.lproj),而不是一个默认版本的资源文件。所有没有本地化的语言的资源文件都会回到这个“默认版本”来。
英文描述中也有暗示:a default version of these files 这“些”文件的一个默认版本,不是一个文件的默认版本。
这里估计是你最大的困惑了,你可能认为这里的文件层级是这样的:
Root
|
+-abc.png
|
+-zh_CN.lproj
|
+-abc.png
按前面的搜索顺序,显然不对,你永远只能获取 Root 下的 abc.png。(事实上也是这样。。。)然而我认为文档中的默认版本指代的是语言文件夹,而不是特定的本地化资源。也就是说结构是这样:
Root
|
+-en.lproj // 指定的 DR 文件夹,你放在根目录下的“默认版本”
| |
| +-abc.png
|
+-zh_CN.lproj
|
+-abc.png
you should place most nonlocalized resources in this top-level directory
非本地化资源放在最顶层,本地化资源放在哪?当然是各个本地化文件夹下面,不然就不叫本地化资源了。
感觉大体上矛盾就在这,剩下的题主自己也能理清楚了。
When looking for resources in your bundle, the bundle-loading code looks first in any region-specific directories, followed by the language-specific directory. And if neither localized directory contains the resource, the bundle-loading code looks for an appropriate nonlocalized resource.
在bundle中搜索资源时,相关代码会首先搜索特定地区目录,然后搜索特定语言目录。如果上述两个地方都没有找到相应的资源,那么会在寻找非本地话资源。
不洗地了,个人认为这段描述确实有错。正确顺序如前文描述。
Then the bundle searches for the resource in the following order:
Global (nonlocalized) resources
Region-specific localized resources (based on the user’s >region preferences)
Language-specific localized resources (based on the user’s language preferences)
Development language resources (as specified by the CFBundleDevelopmentRegion in the bundle’s Info.plist file.)
在bundle中寻找特定资源的顺序如下:1.非本地化资源中 2.地区目录 3.语言目录 4.开发语言目录
就是前文所述的搜索顺序,开发语言目录就是在项目配置中指定的 fallback 。所有没有本地化的语言就会使用这个语言的资源。
Even if you provide localized versions, however, you should always include a default version of these files at the top-level of your application bundle. The default version is used in situations where a specific localization is not available.
即使对某些资源进行了本地化,依然要在根目录下放一个默认版本的文件,以防没有针对某些语言或地区进行本地化。
恩恩,默认版本的本地化文件夹。
Because global resources take precedence over language-specific resources, there should never be both a global and localized version of a given resource. If a global version of a resource exists, language-specific versions of the same resource are never returned.
由于非本地化资源(这里的global就是non-localized,文档中有说明)的优先级高于本地化资源,同一个资源绝对不要同时出现一个本地化版本和一个非本地化版本。如果这样的话,本地化的版本永远不会被获取。
没错。放了的话就成图示1那样了:
Root
|
+-abc.png // 非本地化
|
+-zh_CN.lproj
|
+-abc.png // 本地化(永远不会被获取到)