2009-07-01 5 views
2

Я полный noob для программирования на iPhone, и я столкнулся с тем исключением, что я просто не могу обмотать голову.NSMutableDictionary бросает a doesNotRecognizeSelector в objectForKey?

Справочная информация. Ошибка происходит в пользовательском подзапросе и происходит сразу после загрузки программы. Я получаю исключение, заброшенное в переопределенном методе drawRect. Код метание ошибки следующим образом:

- (void)drawRect:(CGRect)rect{ 
    NSNumber *points = [NSNumber numberWithInt: star.numberOfPoints]; 
    //HERE. Doesn't recognize selector?! 
    CGPathRef t = (CGPathRef)[starPaths objectForKey:points]; 
/*snip*/ 

starPaths инициализируется в awakeFromNib как NSMutableDictionary с мощностью 1.

Исключение становится брошено это - [NSObject doesNotRecognizeSelector:]

starPaths объявлен в заголовочный файл для представления в качестве

NSMutableDictionary *starPaths; 

и инициализируется как

- (void)awakeFromNib{ 
    starPaths = [NSMutableDictionary dictionaryWithCapacity: 1]; 
} 

Наконец, я не смог добраться до точки в коде, где я успешно добавляю элементы в словарь, поскольку код для добавления записи основан на получении ответа от словаря, чтобы узнать, что эта конкретная запись должна быть построена.

Любые предложения? Любая другая информация, которую я должен предоставить? Любая помощь вообще была бы оценена по достоинству, я чувствую, что мне не хватает чего-то очевидного, но я не могу ударить головой весь день.

+1

Не могли бы вы разместить соответствующую часть awakeFromNib, где starPaths инициализируется? – marcc

+1

Также объявление переменной экземпляра для starPaths. Есть ли места, где вы успешно добавляете пары ключ-значение в словарь с -setObject: forKey: и т. Д.? –

ответ

5

Если у вас нет retain переменной starPaths или явным образом выделите ее самостоятельно с помощью [[NSMutableDictionary alloc] initWithCapacity:1], то она будет автоматически выпущена на следующей итерации цикла запуска.

Вам нужно сделать

starPaths = [[NSMutableDictionary dictionaryWithCapacity:1] retain]; 

Или

starPaths = [[NSMutableDictionary alloc] initWithCapacity:1]; 

Просто убедитесь, что release это, когда вам больше не нужно.

+3

Еще лучше, просто используйте установщик в любое время, когда вы хотите установить переменную экземпляра. Это позволяет вашему коду быть согласованным и ставит бремя управления памятью одним способом. – Chuck

+0

Это было бы лучше. – dreamlax

+0

Ага! Я не понимал, что словарь будет освобожден до того, как он ударит по этой точке. Удержание его решило проблему. Благодаря! – Zxaos

1

Несколько вещей, чтобы проверить:

  • ли starPaths объявлена ​​как переменная экземпляра * NSMutableDictionary? Вы отмечаете, что он инициализирован. Вы использовали метод dictionaryWithCapacity (который возвращает объект автоматического выпуска) или initWithCapacity (который должен быть явно сохранен). Чтобы быть в безопасности, вы можете сохранить его и отпустить, когда это будет сделано.

  • Дважды проверьте, правильно ли включены файлы заголовков, поэтому объявление starPaths включено в файлы реализации, которые его используют.

  • Вообще говоря, если вы получаете тайные ошибки, это связано с поврежденной памятью. Попробуйте поставить точку останова в первой строке метода drawRect и сделать «po starPaths» в окне консоли отладчика, чтобы узнать, что в нем и какой тип объекта считает, что среда исполнения.