iPhone/Objective-C阵列枚举崩溃

iPhone/Objective-C阵列枚举崩溃,iphone,objective-c,Iphone,Objective C,这有点复杂 我创建了一个名为pointsOfInterest的数组(NSArray) 此数组的元素是NSDictionary对象。每个字典都有两个键,“headerTitle”和“rowObjects”;“rowObjects”的对象是另一个对象数组;每一个都是一个自定义类 请参阅下面的代码 for (NSDictionary *dict in pointsOfInterest) { NSArray *keys = [dict allKeys]; for (NSString *k

这有点复杂

我创建了一个名为pointsOfInterest的数组(NSArray)

此数组的元素是NSDictionary对象。每个字典都有两个键,“headerTitle”和“rowObjects”;“rowObjects”的对象是另一个对象数组;每一个都是一个自定义类

请参阅下面的代码

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];
}
因此,我在数组中枚举,将各个dictionary对象放入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”键的值。然而,这样做会使应用程序崩溃。奇怪的是,上面的构造很好。。。如果我在内部for循环中离开。如果我删除for循环及其无用的NSLog,只留下以下内容:

for (NSDictionary *dict in pointsOfInterest) {
    NSString *category = [dict valueForKey:@"headerTitle"];
    [poiCategories addObject:category];
}
然后它崩溃了。它不会给我带来任何我能找到的可捕捉的错误


任何人都能想到的任何理由?

编辑路易斯在其中一条评论中指出,
-[NSDictionary valueForKey:
将转发到
objectForKey:
,除非键以
@
开头。不过,为了语义清晰,我还是将其改为使用
objectForKey:


使用
objectForKey:
而不是
valueForKey:
。它们具有非常不同的语义和实现
valueForKey:@“headerTitle”
将查找名为
headerTitle
NSDictionary
方法,并返回该方法的结果(如果该方法不存在,则可能崩溃),而
objectForKey:
实际上是在字典的哈希表结构中查找内容,以找到您要查找的对象。

edit路易斯在
-[NSDictionary valueForKey:]的一条评论中指出
将转发到
objectForKey:
,除非该键以
@
开头。不过,为了语义清晰,我还是将其改为使用
objectForKey:


使用
objectForKey:
而不是
valueForKey:
。它们具有非常不同的语义和实现
valueForKey:@“headerTitle”
将查找名为
headerTitle
NSDictionary
方法,并返回该方法的结果(如果该方法不存在,则可能崩溃),而
objectForKey:
实际上会在字典的哈希表结构中查找内容,以找到您要查找的对象。

-[NSDictionary valueForKey:@“Foo”]实际上会为您调用-[NSDictionary objectForKey:@“Foo”]

因此,两者都适用于国家统计局的词典


至于崩溃,当您在调试器中运行此程序时,是否没有看到堆栈跟踪?poiCategories是一个已分配/初始化的NSMutableArray?

-[NSDictionary valueForKey:@“Foo”]实际上为您调用了-[NSDictionary objectForKey:@“Foo”]

因此,两者都适用于国家统计局的词典


至于崩溃,当您在调试器中运行此程序时,是否没有看到堆栈跟踪?poiCategories是一个已分配/初始化的NSMutableArray?

+1。具体而言,
valueForKey:
是NSObject类别中的键值编码方法
objectForKey:
是您想要的
NSDictionary
特定方法。好的,注意到-但是当添加该循环(包含注释掉的NSLog的循环)时,为什么代码可以工作?valueForKey:和objectForKey:具有不同的语义,但在NSDictionary的情况下valueForKey:不符合您的要求。它实际上会调用objectForKey:除非字符串以@开头,这意味着它会按照他的想法执行。仅当您尝试获取键@“@headertile”的值时,它才会调用超级实现(将尝试方法调用)。看:没问题。我也同意,您应该使用objectForKey:一般来说,当我将字典传递到针对任何KVC对象工作的接口时,我只对字典使用valueForKey:(当然,当代码不知道它是字典时)。我只是想指出,在这种情况下,这并没有导致错误。具体而言,
valueForKey:
是NSObject类别中的键值编码方法
objectForKey:
是您想要的
NSDictionary
特定方法。好的,注意到-但是当添加该循环(包含注释掉的NSLog的循环)时,为什么代码可以工作?valueForKey:和objectForKey:具有不同的语义,但在NSDictionary的情况下valueForKey:不符合您的要求。它实际上会调用objectForKey:除非字符串以@开头,这意味着它会按照他的想法执行。仅当您尝试获取键@“@headertile”的值时,它才会调用超级实现(将尝试方法调用)。看:没问题。我也同意,您应该使用objectForKey:一般来说,当我将字典传递到针对任何KVC对象工作的接口时,我只对字典使用valueForKey:(当然,当代码不知道它是字典时)。我只是想指出,在本例中,这并不是导致错误的真正原因。