2010-08-06 2 views
0

Это немного сложнее.Ошибки перечисления в массиве iPhone/Objective-C

Я создал массив (NSArray), называемый pointOfInterest.

Элементы этого массива - объекты NSDictionary. Каждый словарь имеет два ключа: «headerTitle» и «rowObjects». Значение для «headerTitle» - это простой NSString; объектом для «rowObjects» является другой NSArray объектов; каждый из них является обычным классом.

См. Приведенный ниже код.

for (NSDictionary *dict in pointsOfInterest) { 
    NSArray *keys = [dict allKeys]; 
    for (NSString *key in keys) { 
     //NSLog(@"Key %@",key); 
    }  
    NSString *category = [dict valueForKey:@"headerTitle"]; 
    [poiCategories addObject:category]; 
} 

Итак, я перечисляю массив, получая отдельные словарные объекты в dict. Затем я бег через все свои ключи - если я раскомментировать строку NSLog, он будет отображать что-то вроде этого:

2010-08-06 14:00:17.236 TourGuide[4479:207] Key headerTitle 
2010-08-06 14:00:17.237 TourGuide[4479:207] Key rowObjects 
2010-08-06 14:00:17.238 TourGuide[4479:207] Key headerTitle 
2010-08-06 14:00:17.239 TourGuide[4479:207] Key rowObjects 

Затем строит новый, плоский массив, содержащее значение из всех ключей «headerTitle» ,

Во-первых, я хорошо знаю, что я должен быть в состоянии сделать это:

poiCategories = [[pointsOfInterest valueForKey:@"headerTitle"] retain] 

И получить значения для различных ключей «headerTitle». Однако это приводит к сбою приложения. Что странно, так это то, что выше для построения отлично работает ... ЕСЛИ я ухожу во внутренний цикл. Если я удалю это для цикла и его бесполезный NSLog, оставив только это:

for (NSDictionary *dict in pointsOfInterest) { 
    NSString *category = [dict valueForKey:@"headerTitle"]; 
    [poiCategories addObject:category]; 
} 

Затем он падает. Это не оправдывает меня какой-либо ловушкой, которую я могу найти.

Любые причины, о которых каждый может думать?

ответ

2

редактировать Луис отметил в одном из комментариев, что -[NSDictionary valueForKey:] будет переадресовывать на objectForKey:, если ключ не начинается с @. Source Однако я все равно изменил бы его, чтобы использовать objectForKey: только для смысловой ясности.

Использовать objectForKey: вместо valueForKey:. У них очень разные семантики и реализации. valueForKey:@"headerTitle" будет искать метод NSDictionary с именем headerTitle и вернуть результат этого метода (или, если он не существует, скорее всего, произойдет сбой), тогда как objectForKey: действительно идет и выглядит в структуре таблицы хеш-словаря, чтобы найти объект, ищу.

+1

+1. Чтобы быть конкретным, 'valueForKey:' - метод кодирования по ключевому значению в категории NSObject. 'objectForKey:' - это метод, специфичный для NSDictionary'. – kperryua

+0

Хорошо, отметили - но почему код работает, когда этот цикл (тот, который содержит прокомментированный NSLog), добавлен? –

+0

valueForKey: и objectForKey: имеют разную семантику, но в случае NSDictionary valueForKey: не делает то, что вы требуете.Он фактически вызовет objectForKey: если вы не начинаете строку с @, это означает, что он будет делать то, что он думает. Он выполнит только супер-реализацию (которая будет пытаться вызвать метод), если вы попытаетесь получить значение для ключа @ "@ headerTitle". См. Http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDictionary/valueForKey: –

1

- [NSDictionary valueForKey: @ "Foo"] фактически вызывает - [NSDictionary objectForKey: @ "Foo"] для вас.

Так или будет работать для NSDictionaries.

Что касается сбоев, когда вы запускаете это в отладчике, вы не видите трассировку стека? poiCategories является выделенным/включенным NSMutableArray?

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