Чтение из NSDictionary в NSMutableArray Crash, когда есть только один элемент - PullRequest
1 голос
/ 12 августа 2011

У меня есть NSDictionary, который я получаю данные из файла XML.

XML-файл выглядит так:

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<root>
<customer>
    <areas>
        <area>
            <company>ABC</company>
            <state>OO</state>
            <area_name>Somename</area_name>
            <count>123</count>
            <total_custs>123123</total_custs>
        </area>
       <area>
            <company>BCD</company>
            <state>EE</state>
            <area_name>Somename2</area_name>
            <count>1233</count>
            <total_custs>11233</total_custs>
        </area>
    </areas>
</customer>
</root>

Я прочитал этот xml в NSDictionary, скажем myDict, затем я хочу сохранить его в NSMutableArray, скажем myArray, я использую:

myArray = [[NSMutableArray alloc] initWithArray:[[[[myDict objectForKey:@"root"] objectForKey:@""customer"] objectForKey:@"areas"] objectForKey:@"area"]] autorelease];

Это прекрасно работает, если у меня ноль или два или более <area>, но сбой, если у меня только один, точно так же, как я показал выше.

Вот некоторая информация, которая, на мой взгляд, может быть полезна,

2011-08-12 09:04:40.343 TEST[28595:ef03] -[__NSCFDictionary getObjects:range:]: unrecognized selector sent to instance 0x588af50
2011-08-12 09:04:40.345 TEST[28595:ef03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary getObjects:range:]: unrecognized selector sent to instance 0x588af50'

Часть стека вызовов:

0   CoreFoundation                      0x011fc5a9 __exceptionPreprocess + 185
1   libobjc.A.dylib                     0x01350313 objc_exception_throw + 44
2   CoreFoundation                      0x011fe0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3   CoreFoundation                      0x0116d966 ___forwarding___ + 966
4   CoreFoundation                      0x0116d522 _CF_forwarding_prep_0 + 50
5   CoreFoundation                      0x011f7fc5 -[NSArray initWithArray:range:copyItems:] + 245
6   CoreFoundation                      0x0115fdc0 -[NSArray initWithArray:] + 96

EDIT:

Я думаю, что мог бы просто иметь представление о том, что происходит, поэтому я добавляю оператор if-else, подобный этому:

if ([[[[[myDict objectForKey:@"root"] objectForKey:@""customer"] objectForKey:@"areas"] objectForKey:@"area"] isKindOfClass:[NSArray class]]) {
    ALog(@"is array!");
}
else
{
    ALog(@"not array!");
}

Когда есть только один элемент, он дает мне «нет массива», но я все еще использую initWithArray, чтобы создать свой NSMutableArray.

Таким образом, я могу проверить, является ли объект типом, используя isKindOfClass, есть ли способ просто сказать мне, что это за объект?

Ответы [ 3 ]

1 голос
/ 12 августа 2011

Вы не говорите, как вы перевели XML в словарь, но как из структуры вашего XML, так и из ошибки, area представляется словарем, а не массивом, поэтому вы не можетеиспользуйте его в качестве аргумента для initWithArray:.Предположительно, ваше преобразование из XML в объекты превращает его в массив словарей, когда есть много элементов area, но не тогда, когда есть только один.

0 голосов
/ 12 августа 2011

Я на самом деле немного удивлен, что он работает для 2 или более <area> узлов.Если у вас более одной области, ваш код не поместит все отдельные узлы <area> в массив?Поэтому, когда вы пытаетесь вызвать [areas objectForKey:@"area"], это должно произойти сбой, потому что области это NSArray, а не NSDictionary.Не имеет смысла, что это словарь, потому что он не может иметь дубликаты ключей.Таким образом, если это так, то оно перезаписывает значение, хранящееся в ключе area, если их больше одного.

У меня есть подозрение, что ваш код где-то перевернут - он помещает узлы <area> в словарь, если их 2 или более (вызывает перезапись), и помещает их в массив, если есть только 1(вызывая сбой при вызове метода, который NSArray не имеет значения), но он должен делать обратное.

0 голосов
/ 12 августа 2011

Попробуйте разбить ваши звонки на разные линии, чтобы увидеть, где происходит ошибка.

Вместо этого:

myArray = [[NSMutableArray alloc] initWithArray:[[[[myDict objectForKey:@"root"] objectForKey:@""customer"] objectForKey:@"areas"] objectForKey:@"area"]] autorelease];

Попробуйте это:

NSDictionary *root = [mydict objectForKey:@"root"];
NSDictionary *customer = [root objectForKey:@"customer"];
NSDictionary *areas = [customer objectForKey:@"areas"];
NSDictionary *area = [areas objectForKey:@"area"];
myArray = [[[NSMutableArray alloc] initWithArray: area] autorelease];
...