NSDictionary上的快速枚举失败,“[Waypoint countByEnumeratingWithState:objects:count:]:无法识别的选择器发送到实例...”

时间:2010-01-15 20:10:40

标签: iphone object key nsdictionary fast-enumeration

我在NSDictionary对象中有我的数据,其中键是CGPoints转换为NSValues,对象是UIColors。这是我用来从字典中返回对象的方法:

- (UIColor*) getTemperatureColor2 {
    NSDictionary* temperatureColorMap = [Weather getTemperatureColorMap];   

    for(id key in temperatureColorMap) {
        CGPoint point = [key CGPointValue];
        if ( (int)roundf(self.temperature_celsius) >= (int)roundf(point.x)  ) { 
            if ( (int) roundf(self.temperature_celsius) <= (int) roundf(point.y) ) {
                return [temperatureColorMap objectForKey:key];
            }
        }       
    }

    return [UIColor blackColor];    
}

这是getTemperatureColorMap方法,在同一个类(Weather)中实现:

+ (NSDictionary*) getTemperatureColorMap {
    static NSDictionary* temperatureColorMap = nil;

    if (temperatureColorMap == nil) {
        temperatureColorMap = [[[NSDictionary alloc] initWithObjectsAndKeys:
                            RGB2UIColor(0x0E09EE), [NSValue valueWithCGPoint: CGPointMake(-99, -8)],
                            RGB2UIColor(0xB85FC), [NSValue valueWithCGPoint:  CGPointMake(-7, -3) ],
                            RGB2UIColor(0x0BDCFC), [NSValue valueWithCGPoint: CGPointMake(-2, 2) ],
                            RGB2UIColor(0x1BBA17), [NSValue valueWithCGPoint: CGPointMake(3, 7) ],
                            RGB2UIColor(0x45F90C), [NSValue valueWithCGPoint: CGPointMake(8, 12) ],
                            RGB2UIColor(0xF9F60C), [NSValue valueWithCGPoint: CGPointMake(13, 17) ],
                            RGB2UIColor(0xF9B20C), [NSValue valueWithCGPoint: CGPointMake(18, 22) ],
                            RGB2UIColor(0xF9780C), [NSValue valueWithCGPoint: CGPointMake(23, 27) ],
                            RGB2UIColor(0xFE3809), [NSValue valueWithCGPoint: CGPointMake(28, 32) ],
                            RGB2UIColor(0xFE0909), [NSValue valueWithCGPoint: CGPointMake(33, 99) ], nil] autorelease];
    }

    return temperatureColorMap;
}

我在for循环中调用getTemperatureColor2(遍历所有航点),这都在drawRect方法中。航点包含天气对象。

routeAnnotation.lineColor = [fromWaypoint.weather getTemperatureColor2];

当视图加载时,drawRect方法被调用两次(我需要这个效果)。第一次一切都很好,但第二次代码到达循环的快速枚举时我得到一个异常:

2010-01-15 11:40:42.224 AppName[1601:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[Waypoint countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0x856d170'

现在我不知道Waypoint中的错误是什么,因为它是我正在迭代的NSDictionary。另外,我绝对不明白为什么需要再次调用drawRect来使迭代失败!

2 个答案:

答案 0 :(得分:6)

您希望对字典中的键执行快速枚举,如下所示:

for(NSValue *key in [temperatureColorMap allKeys])

<强>更新
虽然我的建议使意图更加清晰,但它绝对不是你所看到的异常的原因(我现在意识到NSDictionary实现了快速枚举,它必须在键数组上)。

我现在认为它可能是一个内存错误,因为你是自动释放字典(但它的静态引用在它发布时不会被设置为nil),但我无法重现异常甚至运行你的方法很多倍。

我的代码和你的代码之间的唯一区别是我将对RGB2UIColor的调用更改为对Objective-C方法的调用。
你没有提供它的实现,但是我可以假设它能够返回一个正确的Objective-C UIColor对象吗?

答案 1 :(得分:3)

我认为快速枚举的默认数组语法会自动适用于NSDictionary

for(MyClass* instance in dictionary){  // <- this works for NSArray
    // process instance here
}

但是,这似乎会产生 两个 对象(MyClass的实例) 键来自字典(NSString的实例)。由于在MyClass上调用NSString方法,我的应用程序崩溃了。所以我最终这样做了:

for(MyClass* instance in [dictionary allValues]){ // (as opposed to 'allKeys')
    // process instance here
}