从plist读取NSDictionary时BOOL值问题

9

我有以下方法:

- (void)readPlist
{

    NSString *path = [[NSBundle mainBundle] pathForResource:@"States" ofType:@"plist"];    
    self.data = [[NSMutableDictionary alloc] initWithContentsOfFile:path];

    BOOL value = (BOOL)[self.data valueForKey:@"Arizona"];
    NSLog(@"VALUE IS %d", value);

}

它可以正常读取plist文件,可以检测到它有7个键,但是当我尝试打印出值时,如果是no,则返回32,如果是yes,则返回24。我做错了什么?

3个回答

23

valueForKey 返回一个 id。 应该这样做:

NSNumber * n = [self.data valueForKey:@"Arizona"];
BOOL value = [n boolValue];

你不应该使用 valueForKey:。请使用 objectForKey:,或者现在流行的语法 NSNumber * n = self.data[@"Arizona"]; - rmaddy

1
- (void)readPlist
{

NSString *path = [[NSBundle mainBundle] pathForResource:@"States" ofType:@"plist"];    
self.data = [[NSMutableDictionary alloc] initWithContentsOfFile:path];

BOOL value = [[self.data valueForKey:@"Arizona"] intValue];
NSLog(@"VALUE IS %i", value);

}

0

我想在这方面提供一些意见。首先,如何在您的plist中正确定义BOOL值?

Apple's DTD for plist 给出了一个不错的提示:

<!ENTITY % plistObject "(array | data | date | dict | real | integer | string | true | false )" >

然后:

<!-- Numerical primitives -->
<!ELEMENT true EMPTY>  <!-- Boolean constant true -->
<!ELEMENT false EMPTY> <!-- Boolean constant false -->

都很好,但在 plist 中该怎么写呢?

对于真值,应该是:

    <dict>
        <key>employeeId</key>
        <integer>1</integer>
        <key>name</key>
        <string>Joe Smith</string>
        <key>worksRemotely</key>
        <true/>
    </dict>

当然,对于 false:

    <dict>
        <key>employeeId</key>
        <integer>1</integer>
        <key>name</key>
        <string>Joe Smith</string>
        <key>worksRemotely</key>
        <false/>
    </dict>

从plist创建对象时,作为Objectify的热心用户,我从他们的工厂类中获得了灵感。我的Employee类将具有以下方法:

+ (Employee *)instanceFromDictionary:(NSDictionary *)aDictionary {

    Employee *instance = [[Employee alloc] init];

    [instance setAttributesFromDictionary:aDictionary];
    return instance;
}

这将反过来调用:

- (void)setAttributesFromDictionary:(NSDictionary *)aDictionary {

    if (![aDictionary isKindOfClass:[NSDictionary class]]) {
        return;
    }

    [self setValuesForKeysWithDictionary:aDictionary];

}

setValuesForKeysWithDictionary:aDictionaryNSKeyValueCoding Protocol 的成员。这个协议在每个 NSObject 中都可用,这意味着作为 NSObject 的子类,我们的 Employee 类可以免费使用它。

只要我的 Employee 类的属性与 plist 中指定的键值匹配,即 employeeIdnameworksRemotely,那么我就不需要做任何其他事情了。该方法将把 plist 中指定的 worksRemotely 布尔值转换为我的类实例中的正确值:

@property (assign, nonatomic, getter = isWorkingRemotely) BOOL worksRemotely;

只需要迭代plist内容,创建我所需的类的实例即可,bool类型包含在内。
NSString *plistPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"employees" ofType:@"plist"];
NSArray *employeeDictionaries = [NSArray arrayWithContentsOfFile:plistPath];
for (NSDictionary *employeeDict in employeeDictionaries) {
     Employee *employee = [Employee instanceFromDictionary:employeeDict];
     [employees addObject:employee];
}

毫无疑问,我在回答特定问题时有点过头了。但是希望这对那些在尝试创建一个带有布尔值的 plist 的人有所帮助,就像我当初尝试时一样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接