在 plist 中处理持久布尔值的最佳方法?
Posted
技术标签:
【中文标题】在 plist 中处理持久布尔值的最佳方法?【英文标题】:Best way to handle persistent Boolean in plist? 【发布时间】:2010-01-04 15:53:32 【问题描述】:处理从 UISwitch 设置派生并存储在 NSMutableDictionary 中作为持久设置保存到用户目录的布尔值的最佳方法是什么?具体来说,在写入和读取文件系统的 NSMutableDictionary 中,保持布尔值与数值不同的最佳方法是什么?
========
补充说:感谢 Adrian 和 Ben。所以,结果是,如果通过 [NSNumber numberWithBool:] 存储(这是我一直在做的)没有方便的方法来确定该值是否源自布尔值,对吗?
第二部分是我存储的 NSMutableDictionary 最初是通过具有布尔值的 plist 创建它来创建的。这些值在第一次读入时具有 NSCFBoolean 类。现在我的策略是将我在字典中使用的值与 plist 中的相应条目进行比较。
这很重要的原因是我正在动态生成界面元素以允许用户操作这些值,并且我正在将布尔值与 UISwitch 相关联。如果我通过转换为数字丢失了原始类,我会得到一个不合适的用户界面元素。
我正在考虑将数组替换为存储值,其中第一个值是存储值,其余条目是选择:如果存在两个选择,则将其视为布尔值...在其他情况下,它们作为选择器值。但这似乎很麻烦,如果可靠的话。
欢迎任何想法...
【问题讨论】:
是的,有一种方法:在 NSNumber 上使用“objCType”消息。它返回一个 C 字符串:“q”表示整数,“c”表示布尔值,“d”表示双精度。我在下面使用代码 sn-p 编辑了我的答案,显示了您如何看到它。 【参考方案1】:BOOL 值被序列化为 NSNumber 实例,通过 NSNumber 的 numberWithBool: 静态方法创建:
BOOL ok = YES;
NSNumber *value = [NSNumber numberWithBool:ok];
// ...later...
BOOL answer = [value boolValue];
没有其他方法可以序列化 BOOL 值。在生成的 plist 中,如果保存为 XML,BOOL 值显示为
(2010 年 1 月 17 日版)
根据我上面的评论,这段代码可以帮助识别 NSNumber 实例的不同子类型,当它们加载到内存中时,使用“objCType”消息:
NSString *path = [[NSBundle mainBundle] pathForResource:@"untitled"
ofType:@"plist"];
NSArray *array = [NSArray arrayWithContentsOfFile:path];
for (id item in array)
NSLog(@"%@", [NSString stringWithCString:[item objCType]
encoding:NSUTF8StringEncoding]);
untitled.plist 的结构如下:
<plist version="1.0">
<array>
<integer>123</integer>
<true/>
<real>1.2</real>
</array>
</plist>
在这种情况下,上面代码的执行给出了这个:
2010-01-17 17:04:35.100 Untitled[62206:207] q
2010-01-17 17:04:35.101 Untitled[62206:207] c
2010-01-17 17:04:35.102 Untitled[62206:207] d
也许有一种不同的方法来获取存储在 NSNumber 中的数据的内部类型,但这似乎可以解决问题。
【讨论】:
只是一些额外的信息:q
表示 64 位有符号整数,c
表示 BOOL
,即 typedef
-ed 到 ObjC 中的 char
,@987654331 @ 表示double
。
谢谢!我也见过“i”(我想是 32 位整数)。这些值有参考吗?我在 Xcode 捆绑的文档中没有找到任何内容。
愚蠢的我,我在 NSNumber 类参考中找到了答案......它的超类 NSValue。此外,您的 NSValue 方法 objCType 的实现可以返回一组受限的返回值,以便利用非原始方法的抽象实现。有效的返回值是“c” 、“C”、“s”、“S”、“i”、“I”、“l”、“L”、“q”、“Q”、“f”和“d”。”
developer.apple.com/mac/library/documentation/cocoa/Conceptual/…。还有一些更罕见的东西,例如j
用于 C99 _Complex
和 !
用于“gc-invisible”,它们不会出现在 NSNumber
中。【参考方案2】:
您也可以使用常量 kCFBooleanTrue 和 kCFBooleanFalse,不过要将它们添加到 NS 中,您需要将它们转换为 ID:
[myDictionary setObject: (id) kCFBooleanTrue forKey: @"am_I_awesome"];
【讨论】:
【参考方案3】:CFBoolean 对象用于表示 CoreFoundation plist 和集合中的布尔值。使用 CFBoolean 可确保最大的兼容性,尤其是在与第三方软件通信时。
以下函数将 CFBoolean 对象的值作为 C 类型布尔值返回。
Boolean CFBooleanGetValue (CFBooleanRef boolean);
以下常量提供对真假对象的访问。
const CFBooleanRef kCFBooleanTrue;
const CFBooleanRef kCFBooleanFalse;
【讨论】:
以上是关于在 plist 中处理持久布尔值的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章