ios - 在处理 Localizable.stringsdict 时,为什么 String.localizedStringWithFormat 能够以相同的输入产生不同的输出?
问题描述
我有一个Localizable.stringsdict
如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>archived_template</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@VARIABLE@</string>
<key>VARIABLE</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>u</string>
<key>one</key>
<string>Note archived</string>
<key>other</key>
<string>%1$d archived</string>
</dict>
</dict>
<key>clear_lock_message_template</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@VARIABLE@</string>
<key>VARIABLE</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>u</string>
<key>one</key>
<string>%u locked note will be permanently deleted!!!</string>
<key>other</key>
<string>%u locked notes will be permanently deleted!!!</string>
</dict>
</dict>
</dict>
</plist>
令我惊讶的是,即使%#@VARIABLE@
提供相同的输入String.localizedStringWithFormat
,它也能够产生不同的输出。
//
// CASE 1: clear_lock_message_template
//
var formatString : String = NSLocalizedString("clear_lock_message_template", comment: "")
print("formatString : " + formatString)
var resultString : String = String.localizedStringWithFormat(formatString, 1)
print("resultString : " + resultString)
print()
formatString = NSLocalizedString("clear_lock_message_template", comment: "")
print("formatString : " + formatString)
resultString = String.localizedStringWithFormat(formatString, 2)
print("resultString : " + resultString)
print()
//
// CASE 2: archived_template
//
formatString = NSLocalizedString("archived_template", comment: "")
print("formatString : " + formatString)
resultString = String.localizedStringWithFormat(formatString, 1)
print("resultString : " + resultString)
print()
formatString = NSLocalizedString("archived_template", comment: "")
print("formatString : " + formatString)
resultString = String.localizedStringWithFormat(formatString, 2)
print("resultString : " + resultString)
输出
formatString : %#@VARIABLE@
resultString : 1 locked note will be permanently deleted!!!
formatString : %#@VARIABLE@
resultString : 2 locked notes will be permanently deleted!!!
formatString : %#@VARIABLE@
resultString : Note archived
formatString : %#@VARIABLE@
resultString : 2 archived
对于案例 1:clear_lock_message_template和案例 2:archived_template,我们将%#@VARIABLE@
其用作String.localizedStringWithFormat
输入。
但是,为什么它们能够产生不同的正确输出呢?
谢谢。
解决方案
所有值的描述都是一样的。formatString
但它们不是同一个对象。通过查看.stringsdict从 NSLocalizedString 返回的值不仅仅是字符串!它实际上是一个秘密对象类型,__NSLocalizedString
或者,我喜欢称之为 NSLocalizedString。
让我们来看看你的一个(使用 Objective-C):
这是什么???事实证明,在引擎盖下,一个 NSLocalizedString 在其中携带整个.stringsdict对应<dict>
条目。你可以明白为什么。这样,内部键名 (ie VARIABLE
) 可用于在该字典中查找所需的信息。
因此,您的格式字符串之一有效地将整个字典包含在其内部:
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@VARIABLE@</string>
<key>VARIABLE</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>u</string>
<key>one</key>
<string>Note archived</string>
<key>other</key>
<string>%1$d archived</string>
</dict>
</dict>
同时,另一个带有完全不同的字典,即:
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@VARIABLE@</string>
<key>VARIABLE</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>u</string>
<key>one</key>
<string>%u locked note will be permanently deleted!!!</string>
<key>other</key>
<string>%u locked notes will be permanently deleted!!!</string>
</dict>
</dict>
在 Swift 中使用 simple 是看不到这些信息的print
,因为这个对象伪装成一个字符串。然而,正如我们所看到的,它本身包含这些额外的信息。因此,当您String.localizedStringWithFormat
使用该“格式字符串”(NSLocalizedString 对象)调用时,该调用只是直接查看该内部字典以查找 VARIABLE 键的相应信息。
这种架构除了非常聪明之外,也是一件好事,因为否则每个内部键名都必须是唯一的!
推荐阅读
- html - 高度 0 不隐藏 DOM
- proxy - python - 我的代码是否曾经到达代理方法?- 要求
- jenkins - 通过特定的 dockerhub 存储库标签触发 jenkins 作业
- javascript - 如何从jquery中的两个日期获取年龄
- python-3.x - 如何在熊猫的过滤条件中使用分组依据
- wpf - Cefsharp Chrominumwebbrowser 在 WPF 中不起作用
- java - 是否可以在 OWLAPI 中获取名称类的类签名?
- rails-api - 仅在 Rails 5 api 应用程序中处理嵌套属性
- oracle - 创建返回尚未声明的表的函数
- android - Google 登录显示 ERROR 10 (Logs- Wrong OAuth),它在调试应用程序中有效,但在发布 apk 中无效