从 plist 问题中读取带有 BOOL 值的 NSDictionary

发布于 2024-12-08 16:45:45 字数 411 浏览 0 评论 0原文

所以我有以下方法:

- (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个键,但是当我尝试打印该值时,如果它是“否”,它会给我32,如果它是“是”,它会给我24。我做错了什么?

So I have the following method:

- (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);

}

It reads the plist fine, it can detect that it has 7 keys, however when I try to print the value out it gives me 32 if it's a no and 24 if it's a yes. What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

左秋 2024-12-15 16:45:45

valueForKey 返回一个 id。这样做:

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

valueForKey returns an id. Do this:

NSNumber * n = [self.data valueForKey:@"Arizona"];
BOOL value = [n boolValue];
娇妻 2024-12-15 16:45:45
- (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);

}
- (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);

}
花桑 2024-12-15 16:45:45

我想我会参与其中。首先,如何在 plist 中定义 BOOL 值?

Apple 的 plist DTD 给出了一个不错的线索:

<!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 中看起来吗?

好吧,对于 true 值,它会是:

    <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:aDictionary 是 NSKeyValueCoding协议。每个 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 中创建一个具有布尔值的类。

Thought I would chip in on this. First thing is, how to property define a BOOL value in your plist?

Apple's DTD for plist gives a decent clue:

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

and later:

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

All great, but how does that look in the plist?

Well, for a true value, it would be:

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

and of course for false:

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

To create an object from the plist, as a keen user of Objectify, I take inspiration from their factory classes. My Employee class would have these methods:

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

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

    [instance setAttributesFromDictionary:aDictionary];
    return instance;
}

that in turn calls:

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

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

    [self setValuesForKeysWithDictionary:aDictionary];

}

setValuesForKeysWithDictionary:aDictionary is a member of the NSKeyValueCoding Protocol. That's available with every NSObject which means as as a subclass of NSObject, our Employee class gets that for free.

As long as my Employee class' properties match with the key values specified in the plist, namely employeeId, name, and worksRemotely, then I won't need to do anything else. That method will translate the worksRemotely boolean specified in the plist to the correct value in my class instance:

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

All that's left is to iterate through the plist contents, creating the instances of my desired class, bool included:

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];
}

No doubt I've gone a bit over the top in answering the specific question. However hopefully this can be of use to someone else who stumbled across this question whilst trying to do what I was trying, i.e. create a class with a boolean value in a plist.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文