2013-03-01 2 views
0

Я с трудом извлекая словарь из многоуровневого массива, который объявлен как:Извлечение словаря из многоуровневого массива с помощью indexPath.row

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"]; 
+0

добавить содержание MENUITEM массива в вашем вопросе. –

+0

Почему вы думаете, что 'menuItems' является массивом? –

+0

Он объявлен как массив, поэтому я не могу получить к нему доступ с помощью indexForKey: – Jimmypooza

ответ

1

Используйте следующий код:

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

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

Это будет возвращать только для первого массива: Ваш может также получить все значения с помощью for Loop:

2

Objective-C - довольно динамичный язык, поэтому даже если у вас есть menuItems, объявленный как NSArray, нет гарантий относительно его s во время выполнения. Если вы отделили объект JSON от своего вопроса и назначили его menuItems, вы фактически назначаете ему экземпляр NSDictionary. Обратите внимание, что внешние символы JSON являются фигурными фигурами, представляющими объект (который преобразуется в NSDictionary), а не квадратные скобки, представляющие массив. Этот объект имеет один ключ, Table, с массивом как связанное значение.

Так что вам нужно сделать, это что-то вроде этого:

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

Где JSONObject является то, что вы в данный момент присвоения menuItems. После этого menuItems указывает на массив словарей, каждый из которых должен быть в состоянии дать вам нужные вам строки.

1

То есть, что отправляется вам с помощью строки JSON. Он начинается с пары ключ-значение, заключенной в {}. У него есть только одна запись. Ключом этой записи является «таблица», и ее значение представляет собой массив, который обертывает несколько объектов. Объекты массива заключены в []. Witin массив - это множество наборов пар ключ/значение (заключено в {}).

Таким образом, каждый {} будет преобразован в 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: и т. Д. Просто вернет нуль, если ключ не существует. Но objectAtIndex:0 вызовет недопустимое исключение аргумента, если в массиве нет объекта. Поэтому убедитесь, что вы проверяете длину и существование полученных объектов.

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

сделаю. Это сначала проверяет, не является ли menuItem не нулем, а затем проверяет, является ли он NSArray (или NSMutableArray - который будет эвальтировать к YES тоже) и независимо от того, содержит ли массив какой-либо объект вообще. Последнее было бы достигнуто с помощью правильной петли. Нет необходимости фактически вставлять операторы if, потому что он начинает оценивать слева и перестает оценивать первый NO, который обнаружен, когда все условия связаны с логическим И &&.

+0

Спасибо за ответ, включит это в мой код. – Jimmypooza

+0

Это отличный ответ, я закладок. –

0

Спасибо за ответы, они были действительно полезны. Я изменил NSArray *menuItems; к NSDictionary *menuItems;, а затем сделал это:

NSDictionary *tweet = [[menuItems objectForKey:@"Table"] objectAtIndex:indexPath.row]; 
NSString *text = [tweet objectForKey:@"MENUDESC"]; 
NSString *name = [tweet objectForKey:@"MENUID"]; 

Который работал отлично, дал мне этот результат:

2013-03-02 03:00:44.396 App Test[616:c07] HOME    ID:1072 
2013-03-02 03:00:44.396 App Test[616:c07] PRODUCTS &amp; SERVICES ID:1073 
2013-03-02 03:00:44.396 App Test[616:c07] ABOUT US ID:1074 
2013-03-02 03:00:44.397 App Test[616:c07] WHAT SETS US APART ID:1075 
2013-03-02 03:00:44.397 App Test[616:c07] CASE STUDIES ID:1126 
2013-03-02 03:00:44.397 App Test[616:c07] REQUEST PROPOSAL ID:1076 
2013-03-02 03:00:44.397 App Test[616:c07] CONTACT ID:1077 
+0

Поскольку другие пользователи помогли вам, в частности (судя по вашему замечанию), Герман Клеккер, вежливо принять ответ, который разрешил вашу проблему. Я заметил по вашим другим вопросам, которые вы прокомментировали, указав, что какой-то пользователь помог, или что-то, что было указано в ответе, помогло, но вы не приняли ни одного из ответов. Поэтому, если вы не знаете, я просто даю вам знать об этом аспекте сайта. Если вы знаете о роли принятия уже, то, пожалуйста, не обращайте внимания на этот комментарий, я не пытаюсь принуждать или пилить, просто воспитывать. Удачи. –

Смежные вопросы