1

この P リスト ディクショナリを考えると、次のようになります。

ここに画像の説明を入力

3位になるにはどうすればいいですか?キー - 「ディナー」 - それ自体が辞書でもあり、その値を正しく解析しますか?

それとも、すべてをより簡単に理解できるように、この P リストを最初から別の方法で構成する必要がありますか?

「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」メソッドを使用する必要がありますか?

私はこれを試しました - 動作しません:

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

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

「ディナー」キーの内容で初期化したいのですが、明らかに P リスト ファイルではないため、使用できません

   initWithContentsOfFile: pathName

「ディナー」のキーと値の両方にアクセスできる他の init メソッドがどれかわかりません。「夕食」は辞書として構造化されていますが、現在は配列内にあり、辞書とは見なされないためです(私は思う...)

私は明らかにこれについて少し不明です。

それとも、このネストされたディナー ディクショナリを取得できるように、最初から P リストを別の方法で構造化する必要がありますか?

何か案は?

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

meanTimeが「Dinner」の場合、mealDishesArrayにNSDictionaryである値を割り当てています。配列があると思ったら、次のように使用します。

for (NSString *dish in mealDishesArray)

'Dinner'に期待するものを提供しない配列内の要素を反復処理します。次のようなものを追加することを検討してください。

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

meanDishesArrayへの割り当て後。

解決策は何ですか?PLISTの構造は、「朝食」、「昼食」、「夕食」でまったく異なります。'Dinner'がNSDictionaryであり、他がNSArrayであるのはなぜですか?それらをすべて同じタイプにします。できない場合は、以下に基づいてコードを条件付けする必要があります。

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

何かを割り当てたり、ファイルから何かを読み取ったりする必要はありません。'Dinner'データの辞書がすでにあります。

于 2012-04-21T21:34:14.920 に答える