3

我在 NSDictionary 对象中有我的数据,其中键是转换为 NSValues 的 CGPoints,对象是 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 方法:

+ (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 才能使迭代失败!

4

2 回答 2

6

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

for(NSValue *key in [temperatureColorMap allKeys])

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

我现在认为这可能是一个内存错误,因为您正在自动释放字典(但它的静态引用在释放时不会设置为 nil),但即使多次运行您的方法,我也无法重现异常。

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

于 2010-01-15T20:27:12.450 回答
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
}
于 2013-05-16T08:45:31.477 回答