2010-09-15 2 views
0

У меня есть Plist файл:Оспаривание Plist переборе и NSDictionary проблемы

Root - Dictionary 
    categories - Array 
    item 0 - Dictionary 
    item 1 - Dict 
    item 2 - Dict 

я загрузить файл, как так:

-(void) loadCategories 
{ 
    // Loads the categories from the SymbolList.plist file 
    NSString *file = [[NSBundle mainBundle] pathForResource:@"SymbolList" ofType:@"plist"]; 
    NSMutableDictionary *plistSymbolList = [[NSMutableDictionary alloc] initWithContentsOfFile:file]; 

    categoriesList = [plistSymbolList objectForKey:@"categories"]; 
    NSLog(@"count is: %d", [categoriesList count]); 

    // Here I am just testing if this method will work 
    for(int i = 0; i < [categoriesList count]; i++) 
    { 
     NSDictionary *dict = [categoriesList objectAtIndex:i]; 
     NSLog(@"dict count: %d", [dict count]); 
    } 

    // ideally this is what I'd like to do but doesn't work on device 
    for (NSDictionary *dictionary in categoriesList) 
    { 
     if (dictionary == nil) 
      NSLog(@"It's nil."); 

     NSLog(@"count: %d", [dictionary count]); 

     // get and display the category information 
     NSString *catName = [dictionary objectForKey:@"Category Name"]; 
     NSLog(@"catName is: %@", catName); 
     NSString *catImage = [dictionary objectForKey:@"Category Image"]; 
     NSLog(@"catImage is: %@", catImage); 

     NSString *fullFile = [NSString stringWithFormat:@"%@.png", catImage]; 
     NSLog(@"Full file name is: %@", fullFile); 

     SymbolButton *categoryButton = [[SymbolButton alloc] initWithName:catName andSymbol:catImage]; 
     [categoryButton addTarget:self action:@selector(categoryButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 
     [categoryButtonList addObject:categoryButton]; 
     NSLog(@"Added Button to list"); 
    } 

    [self updateCategories];  

Просто резюмировать Я: 1) при загрузке файла, чтобы получить мой корень 2) получение моего списка категорий 3) прохождение через каждый из них и получение какого-либо значения либо с помощью объекта objectAtIndex OR objectForKey

ВСЕ этот код работает GREAT на эмуляторе и отлично работает без сбоев. Эта функция СКОНЧАЛСЯ как только я запустить его на устройстве:

TestApp[4734:207] count is: 3 
TestApp[4734:207] *** -[NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x122d10 
TestApp[4734:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x122d10' 

Из сообщения об ошибке это говорит существует проблема с моими экземплярами. Но почему это будет работать на сим, а не на устройстве? Все обновляется до последней SDK и версии ОС (не бета) и т.д.

Если я закомментируйте первый цикл я получаю:

TestApp[4760:207] count is: 3 
TestApp[4760:207] *** -[NSCFString count]: unrecognized selector sent to instance 0x120470 
TestApp[4760:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFString count]: unrecognized selector sent to instance 0x120470' 

Спасибо за любую помощь и все. Это убивает меня :)

+0

«Эта функция DIES, как только я запускаю ее на эмуляторе» - вы имели в виду, «... запустить ее на устройстве»? – egrunin

+0

Извините, да .. редактирование сейчас. Он умирает, когда я запускаю его на устройстве. –

ответ

0

Оказывается, проблема связана с файлом plist, который имеет несколько типов.

У меня был Plist файл, который был:

NSDictionary 
- NSArray 
    - Item 0 
    - Name - String 
    - Category - String 
    - Image - String 
    - Item 1 
    - Name - String 
    - Category - String 
    - Image - String 
    - Item 2 
    - Name - String 
    - Category - String 
    - Image - String 

эмулятор обрабатывается эту прекрасную загрузку, как я уже говорил выше. Однако устройство просто не будет правильно читать элементы.

Я переключил свой файл Plist быть:

NSArray 
    - Item 0 
    - Name - String 
    - Category - String 
    - Image - String 
    - Item 1 
    - Name - String 
    - Category - String 
    - Image - String 
    - Item 2 
    - Name - String 
    - Category - String 
    - Image - String 

Корень является массив, и это продолжается в нормальном режиме с этого момента.

Я думал, может быть, я читал в объекте, когда это должно было быть значение, но это было не так. Однако информация об отладке указывает на это. Это все еще кажется странным, но теперь он отлично работает как в эмуляторе, так и на устройстве.

Надеюсь, это поможет любому, у кого есть эта проблема.

0

Три вещи: Сначала я думаю, что вы должны использовать valueForkey: not objectForKey: Я предполагаю, что у вас есть String в словаре. Что-то вроде этого:

NSString *catName = [dict valueForKey:@"Category Name"]; 

Во-вторых, почему бы не переместить все из NSString * catName = [словарь objectForKey: @ "Название категории"]; в первый цикл for и сделать NSString * catName = [dict objectForKey: @ "Category Name"]; вместо? Если делать ту же работу Таким образом, вы бы что-то вроде этого:

for(int i = 0; i < [categoriesList count]; i++) 
{ 
NSDictionary *dict = [categoriesList objectAtIndex:i]; 
NSLog(@"dict count: %d", [dict count]); 
NSString *catName = [dict objectForKey:@"Category Name"]; 
NSLog(@"catName is: %@", catName); 
NSString *catImage = [dict objectForKey:@"Category Image"]; 

}

Третье: я не думаю, что [словарь число] будет работать, попробуйте принимать это.

Надеется, что это помогает

+0

Спасибо за помощь! Я попробовал ваши предложения. Я использую строку для значения, поэтому переключил ее на valueForKey, но не увидел никаких изменений. Я также попытался удалить счетчик [dictionary count]. Все равно никаких изменений. Все это нормально работает на эмуляторе, но НЕ на устройстве. Кажется очень странным. Любые другие идеи? –

+0

Кроме того, почему это не работает: NSDictionary * dictionary = (NSDictionary *) [categoriesList objectAtIndex: 0]; Так как это должно вернуть первый NSDictionary в categoryList. Помните, что я знаю, что в моем списке есть 3 объекта, потому что я сообщаю счету списка, прежде чем пытаться его назначить. –

0

Вы можете читать другую версию файла Plist на тренажере, чем тот, который в настоящее время на телефоне. Проблема в первом цикле заключается в том, что, очевидно, categoriesList, хранящийся в plist на симуляторе, представляет собой массив, тогда как один на телефоне является словарем.

Если вы внимательно посмотрите на лог сообщения:

-[NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x120470 

вы увидите, что это говорит вам, что именно эта проблема: вы послав -objectAtIndex: сообщение для экземпляра NSDictionary (NSCFDictionary является частный подкласс NSDictionary).

Ваш код должен компилироваться с предупреждением на этой строке. Немного советов: не игнорируйте предупреждения в Objective-C! Обычно они указывают на серьезные проблемы, многие из которых могут привести к летальному исходу.

Проблема во втором цикле аналогична, и снова сообщение журнала сообщает вам все, что вам нужно знать: вы отправляете сообщение -count экземпляру NSString, который, по-видимому, ваш код, по-видимому, будет NSDictionary.

+0

Спасибо за совет. Мой код на самом деле не компилируется с любыми предупреждениями или проблемами. Предупреждения такие же, как ошибки, и я никогда не позволял им скользить. Файл на устройстве - тот же файл, что и на эмуляторе. Я беспокоился об этом и несколько раз проверял. -Count должен быть вызван в словаре или списке в зависимости от того, где в коде вы ссылаетесь. Проблема заключается в том, что устройства, имеющие отношение к NSDict с NSArray с несколькими NSDicts под этим. Кажется странным. –

+0

Извините, у вас плохое представление о 'categoryList' ivar в отсутствие объявления. В любом случае проблема возникает из-за несоответствия фактической структуры plist и ожидаемого кода. – jlehr

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

  • Нет связанных вопросов^_^