0

次のように宣言されているマルチレベル配列から辞書を抽出するのが困難です。

NSArray *menuItems;次のようになります。

Table =     (
                {
            MENUDESC = "HOME           ";
            MENUID = 1072;
            NAVIGATETO = "content.aspx?item=1072&pid=0";
            NAVIGATETO2 = "default.aspx?item=1072&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "PRODUCTS &amp; SERVICES";
            MENUID = 1073;
            NAVIGATETO = "#";
            NAVIGATETO2 = "default.aspx?item=1073&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "ABOUT US";
            MENUID = 1074;
            NAVIGATETO = "content.aspx?item=1074&pid=0";
            NAVIGATETO2 = "default.aspx?item=1074&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "WHAT SETS US APART";
            MENUID = 1075;
            NAVIGATETO = "content.aspx?item=1075&pid=0";
            NAVIGATETO2 = "default.aspx?item=1075&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "CASE STUDIES";
            MENUID = 1126;
            NAVIGATETO = "content.aspx?item=1126&pid=0";
            NAVIGATETO2 = "default.aspx?item=1126&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = "REQUEST PROPOSAL";
            MENUID = 1076;
            NAVIGATETO = "content.aspx?item=1076&pid=0";
            NAVIGATETO2 = "default.aspx?item=1076&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        },
                {
            MENUDESC = CONTACT;
            MENUID = 1077;
            NAVIGATETO = "contactus.aspx?item=1077&pid=0";
            NAVIGATETO2 = "contactus.aspx?item=1077&pid=0";
            PARENTMENUID = "<null>";
            PROTECTED = "<null>";
            parentmenuid2 = "<null>";
        }
    );
}

次のような JSON から作成されます。

{
  "Table": [
    {
      "MENUID": 1072.0,
      "MENUDESC": "HOME           ",
      "PARENTMENUID": null,
      "NAVIGATETO": "content.aspx?item=1072&pid=0",
      "NAVIGATETO2": "default.aspx?item=1072&pid=0",
      "PROTECTED": null,
      "parentmenuid2": null
    },
    {
      "MENUID": 1073.0,
      "MENUDESC": "PRODUCTS &amp; SERVICES",
      "PARENTMENUID": null,
      "NAVIGATETO": "#",
      "NAVIGATETO2": "default.aspx?item=1073&pid=0",
      "PROTECTED": null,
      "parentmenuid2": null
    },
    {
      "MENUID": 1074.0,
      "MENUDESC": "ABOUT US",
      "PARENTMENUID": null,
      "NAVIGATETO": "content.aspx?item=1074&pid=0",
      "NAVIGATETO2": "default.aspx?item=1074&pid=0",
      "PROTECTED": null,
      "parentmenuid2": null
    },
    {
      "MENUID": 1075.0,
      "MENUDESC": "WHAT SETS US APART",
      "PARENTMENUID": null,
      "NAVIGATETO": "content.aspx?item=1075&pid=0",
      "NAVIGATETO2": "default.aspx?item=1075&pid=0",
      "PROTECTED": null,
      "parentmenuid2": null
    },
]
}

これを使用して辞書を抽出するサンプルコードを使用しています。

NSDictionary *items = [menuItems objectAtIndex:indexPath.row];

しかし、それは機能していません。「無効なセレクターが送信されました」というエラーが表示されます。配列内のデータにアクセスするためにあらゆる種類の方法を試しました。しかし、私が見つけたすべての調査と回答は役に立ちません。

次のように NSStrings を作成する必要があります。

NSString *text = [[menuItems objectForKey:@"Table"] objectForKey:@"MENUDESC"];
NSString *name = [[menuItems objectForKey:@"Table"] objectForKey:@"MENUID"];
4

4 に答える 4

2

Objective-C はかなり動的な言語であるため、menuItemsとして宣言したとしてもNSArray、実行時にその型が保証されるわけではありません。質問から JSON オブジェクトをデシリアライズし、それをmenuItemsに割り当てた場合、実際にはそれにNSDictionaryインスタンスを割り当てています。JSON の最も外側の記号は、オブジェクト ( に変換されるNSDictionary) を表す中括弧であり、配列を表す角括弧ではないことに注意してください。このオブジェクトにはTable、関連付けられた値として配列を持つ 1 つのキーがあります。

だからあなたがする必要があるのは次のようなものです:

NSArray *menuItems = JSONObject[@"Table"];

JSONObjectは、現在 に割り当てているものですmenuItems。その後、menuItems辞書の配列を指し、それぞれが必要な文字列を提供できるはずです。

于 2013-03-01T08:29:52.347 に答える
1

次のコードを使用します。

NSLog(@"%@",[[[menuItems objectForKey:@"Table"] objectAtIndex:0] objectForKey:@"MENUDESC"]);

NSLog(@"%@",[[[menuItems objectForKey:@"Table"] objectAtIndex:0] objectForKey:@"MENUID"]);

これは最初の Array に対してのみ返されます: を使用してすべての値を取得することもできますfor Loop:

于 2013-03-01T08:28:17.637 に答える
1

つまり、JSON 文字列によって送信されるものです。{} で囲まれたキーと値のペアで始まります。エントリは 1 つだけです。そのエントリのキーは「テーブル」で、その値は多数のオブジェクトをラップする配列です。配列のオブジェクトは [] で囲みます。配列内には、キーと値のペアのセットがいくつかあります ({} で囲まれています)。

したがって、各 {} は、キーと値のペアの適切なコンテナーである NSDictionary に変換されます。そして、すべての [] は、空のものであっても、オブジェクトの NSArray に変換されます。

何を受け取るかは決してわかりません。したがって、受け取った値が NSArray、NSDictionary、NSString、または NSNumber であるかどうかを常に再確認する必要があります。(率直に言って、NSDateについてはよくわかりません。)(例)を使用してそれを行います

if ([myCurrentObject isKindOfClass[NSString class]]) {
  // process the data
} else {
  // react to the error because you were expecting a string and got something else
}

そうすることで、データを処理できない場合でも、アプリが適切に反応する可能性が高まります。これは、現在観察されているキャッチされていない例外による中止よりもはるかに優れています。

空の配列とディクショナリも受け取る準備をしてください。辞書の場合はそれほど難しくありません。objectForKey:キーが存在しない場合、etc は単純に nil を返します。ただしobjectAtIndex:0、配列内にオブジェクトがない場合は、無効な引数の例外がスローされます。そのため、受信したオブジェクトの長さと存在を確認してください。

if (menuItems && [menuItems isKindOfClass[NSArray class]] && [menuItems count]) ... 

しましょう。最初に menuItem が nil でないかどうかをチェックし、次にそれが NSArray (または NSMutableArray - これも YES に評価されます) であるかどうか、および配列にオブジェクトが含まれているかどうかをチェックします。後者は、適切な for ループでも実現できます。if ステートメントを実際にネストする必要はありません。これは、左側から評価を開始し、すべての条件が論理 AND で接続されている場合に見つかった最初の NO で評価を停止するため&&です。

于 2013-03-01T16:16:58.370 に答える