1

鉴于此 P-List 字典:

在此处输入图像描述

怎么才能到3楼。关键 - “晚餐” - 它本身也是一个字典,并正确解析其值?

或者,我应该以不同的方式开始构建这个 P-List,以便我可以更轻松地了解所有内容吗?

这是我得到的,首先从我的“MenuDictionary”中获取所有键并将它们存储在一个数组中:

// Load the Property-List file into the Dictionary:
MenuDictionary = [[NSDictionary alloc] initWithContentsOfFile:menuPath];

// Get all the Keys from the Dictionary, put 'em into a 'mealTimesArray':
mealTimesArray = [[MenuDictionary allKeys] sortedArrayUsingSelector:@selector(compare:)];

// For each meal-type KEY, grab all the Values (dishes) in it and store them in a 'mealDishesArray':
for (NSString *mealTime in mealTimesArray) {
    NSArray *mealDishesArray = [MenuDictionary valueForKey:mealTime];

    // Now I can iterate through the 'mealDishesArray' to access each dish at
    // a time, so I can print them out or do whatever else:
    for (NSString *dish in mealDishesArray) {
        NSLog(@"Iterating through 'mealDishesArray' now...");
        NSLog(@"Current 'dish' is: %@", dish);

当我到达“晚餐”键时出现问题:它是一个字典,包含 2 个键和 2 个数组值。那么如何将其内容加载到 Dictionary 对象中呢?更具体地说,我应该使用什么“init”方法将“Dinner”内容加载到我的新 Dictionary 对象中?

我试过这个 - 不起作用:

// I put this inside the first fast-enum loop:

if ([mealTime isEqualToString: @"Dinner"]) {
   // init new Dictionary object (declared previously):
   dinnerDictionary = [[NSDictionary alloc] initWith ???];

我想用“晚餐”键的内容来初始化它,但它显然不是 P-List 文件,所以我不能使用

   initWithContentsOfFile: pathName

我不明白其他哪个 init 方法可以让我访问“Dinner”的键和值。因为即使“晚餐”的结构是字典,它目前位于一个数组中,它并不认为它是字典(我认为......)

我对此显然有点不清楚。

或者,我应该以不同的方式开始构建我的 P-List 以便我可以获取这个嵌套的晚餐字典吗?

有任何想法吗?

4

2 回答 2

1

我认为 plist 结构是有意义的,并且基于类有条件地处理内容也完全可以。我会在合理的期望范围内对 plist 中的内容做出反应,所以......

// for each meal...
for (NSString *mealTime in mealTimesArray) {
    // we're not sure what kind of meal we have
    id mealInfo = [MenuDictionary valueForKey:mealTime];

    if ([id isKindOfClass:[NSArray self]]) {
        // it's an array? cast as an array and deal with the array
        NSArray *mealDishesArray = (NSArray *)mealInfo;
        [self handleMealArray:mealDishesArray];
    } else if ([id isKindOfClass:[NSDictionary self]]) {
        // it's a dictionary?  that's cool, too. cast as a dictionary and deal with it
        NSDictionary *mealDictionary = (NSDictionary *)mealInfo;
        [self handleMealDictionary:mealDictionary];
    }
}

// you've worked out to handle the array
- (void)handleMealArray:(NSArray *)mealDishesArray {
    for (NSString *dish in mealDishesArray) {
        NSLog(@"Iterating through 'mealDishesArray' now...");
        NSLog(@"Current 'dish' is: %@", dish);
    }
}

// handle the dictionary like a dictionary, realizing that it contains
// arrays, which you've already worked out how to handle
- (void)handleMealDictionary:(NSDictionary *)mealDictionary {
    for (NSString *dishType in [mealDictionary allKeys]) {
        NSArray *mealDishesArray = [mealDictionary valueForKey:dishType];
        [self handleMealArray:mealDishesArray];
    }
}
于 2012-04-21T21:51:10.593 回答
0

“问题”出在这一行:

NSArray *mealDishesArray = [MenuDictionary valueForKey:mealTime];

当mealTime 为'Dinner' 时,您正在为mealDishesArray 分配一个NSDictionary 值。认为您有一个数组,然后使用:

for (NSString *dish in mealDishesArray)

迭代数组中的元素,这不会给你你对“晚餐”的期望。您可以考虑添加如下内容:

NSAssert ([mailDishesArray isKindOfClass: [NSArray class]], @"Expecting an array");

在你分配到 mealDishesArray 之后。

解决办法是什么?您的 PLIST 在“早餐”、“午餐”和“晚餐”之间具有完全不同的结构。为什么 'Dinner' 是 NSDictionary 而其他的是 NSArray?使它们都具有相同的类型。如果不能,那么您必须根据以下条件对代码进行条件化:

if ([mealTime isEqualToString: @"Dinner"]) {
   NSDictionary *dinnerDictionary = (NSDictionary *) [MenuDictionary valueForKey:mealTime];
   /* ... */ }

您不需要分配任何内容或从文件中读取任何内容;您已经有一个用于“晚餐”数据的字典。

于 2012-04-21T21:34:14.920 回答