быстрое перечисление в NSDictionary завершается неудачно с "[Waypoint countByEnumeratingWithState: objects: count:]: нераспознанный селектор, отправленный экземпляру ..." - PullRequest
3 голосов
/ 15 января 2010

У меня есть данные в объекте 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];    
}

Это метод getTemperaColorMap, реализованный в этом же классе (погода):

+ (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;
}

Я вызываю getTemperaColor2 в цикле for (проходящем через все путевые точки), который есть в методе 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 ]

6 голосов
/ 15 января 2010

Вы хотите выполнить быстрое перечисление ключей в словаре следующим образом:

for(NSValue *key in [temperatureColorMap allKeys])

ОБНОВЛЕНИЕ
Хотя мое предложение проясняет намерение, оно определенно непричина исключения, которое вы видите (теперь я понимаю, что NSDictionary реализует быстрое перечисление, и оно должно быть в массиве ключей).

Теперь я думаю, что это может быть ошибка памяти, так как вы автоматически высвобождаете словарь (но статическая ссылка на него не устанавливается равной нулю, когда он выпущен), но я не могу воспроизвести исключение, даже работаяВаш метод много раз.

Единственное различие между моим и вашим кодом состоит в том, что вместо этого я изменил вызов RGB2UIColor на вызов метода Objective-C.
Вы не предоставили его реализацию, но могу ли я предположить, что этоможет вернуть правильный объект -IC UIColor объект?

3 голосов
/ 16 мая 2013

Я думал, что синтаксис массива по умолчанию для быстрого перечисления будет автоматически работать для 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
}
...