【问题标题】:iPhone/Objective-C array enumeration crashesiPhone/Objective-C 数组枚举崩溃
【发布时间】:2010-08-06 21:16:43
【问题描述】:

这有点复杂。

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

这个数组的元素是 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”键的值。但是,这样做会使应用程序崩溃。奇怪的是,上面的 for 构造工作正常……如果我留在内部 for 循环中。如果我删除那个 for 循环,以及它无用的 NSLog,只留下这个:

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

然后它崩溃了。它不会因我能找到的任何类型的可捕获错误而使我感到高兴。

任何人都可以想到的任何原因?

【问题讨论】:

    标签: iphone objective-c


    【解决方案1】:

    edit Louis 在其中一个 cmets 中指出,-[NSDictionary valueForKey:] 将转发到 objectForKey:,除非密钥以 @ 开头。 Source 但是,为了语义清晰,我仍然会将其更改为使用 objectForKey:

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

    【讨论】:

    • +1。具体来说,valueForKey: 是 NSObject 类别中的 Key-Value Coding 方法。 objectForKey:NSDictionary 想要的特定方法。
    • 好的,注意到了 - 但是为什么当添加那个循环(包含注释掉的 NSLog 的那个)时代码可以工作?
    • valueForKey: 和 objectForKey: 具有不同的语义,但在 NSDictionary 的情况下 valueForKey: 不符合您的要求。它实际上会调用 objectForKey: 除非你的字符串以 @ 开头,这意味着它会按照他的想法去做。如果您尝试获取键 @"@headerTitle" 的值,它只会调用超级实现(它将尝试方法调用)。见developer.apple.com/mac/library/documentation/Cocoa/Reference/…:
    • 没问题。我也同意,您应该使用 objectForKey: 一般来说,我只在将字典传递到适用于任何 KVC 对象的接口时才使用 valueForKey: 对字典(IOW,当代码不知道它是字典时) )。我只是想指出在这种情况下实际上并没有导致错误。
    【解决方案2】:

    -[NSDictionary valueForKey:@"Foo"] 实际上为你调用了 -[NSDictionary objectForKey:@"Foo"]。

    所以任何一个都适用于 NSDictionaries。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-14
      相关资源
      最近更新 更多