在plist中处理持久性布尔值的最佳方法?

时间:2010-01-04 15:53:32

标签: iphone objective-c boolean nsmutabledictionary nsnumber

处理从UISwitch设置派生的布尔值的最佳方法是什么,并存储在作为持久设置保存到用户目录的NSMutableDictionary中?具体来说,在文件系统中写入和读取的NSMutableDictionary中保持布尔值与数值不同的最佳方法是什么?

======

补充道:感谢Adrian和Ben。因此,结果是如果通过[NSNumber numberWithBool:]存储(这是我一直在做的),没有方便的方法来确定该值是否来自布尔值,是否正确?

第二部分是我存储的NSMutableDictionary最初是通过具有布尔值的plist创建的。这些值在第一次读入时具有类NSCFBoolean。现在我的策略是将我在字典中使用的值与plist中的相应条目进行比较。

这个问题的原因是我正在动态生成界面元素以允许用户操纵这些值,并且我将布尔值与UISwitch联系起来。如果我通过转换为数字而丢失原始类,则会得到不合适的用户界面元素。

我正在考虑将数组替换为存储值,其中第一个值是存储值,其余条目是选择:如果存在两个选项,则将其视为布尔值...在其他情况下,它们作为选择器值。但这似乎很麻烦,如果可靠的话。

欢迎任何想法......

3 个答案:

答案 0 :(得分:11)

BOOL值被序列化为NSNumber实例,通过NSNumber的numberWithBool创建:静态方法:

BOOL ok = YES;
NSNumber *value = [NSNumber numberWithBool:ok];

// ...later...

BOOL answer = [value boolValue];

没有其他方法可以序列化BOOL值。在生成的plist中,如果保存为XML,则BOOL值显示为< true />和< false />实体。

(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中的内部数据类型,但这似乎可以解决问题。

答案 1 :(得分:3)

您也可以使用常量kCFBooleanTrue和kCFBooleanFalse,但是要将这些常量添加到NS中,您需要将它们作为ID投射:

[myDictionary setObject: (id) kCFBooleanTrue forKey: @"am_I_awesome"];

答案 2 :(得分:1)

CFBoolean对象用于表示CoreFoundation plists和集合中的布尔值。使用CFBoolean可确保最大程度的兼容性,尤其是在与第三方软件通信时。

以下函数将CFBoolean对象的值作为C类型布尔值返回。

Boolean CFBooleanGetValue (CFBooleanRef boolean);

以下常量提供对true和false对象的访问。

const CFBooleanRef kCFBooleanTrue;
const CFBooleanRef kCFBooleanFalse;