2009-06-22 4 views
2

У меня есть массив из 5 элементов, который также используется в качестве содержимого для таблицы. В nib - кнопка, которая изменяет содержимое массива на 5 разных элементов. Однако при нажатии этой кнопки приложение вылетает с EXC_BAD_ACCESS. Я установил точку останова на objc_exception _throw и подтвердил мои подозрения. Плохой методПри изменении массива DataSource TableView, сбой приложения

- (id)tableView:(NSTableView *)wordsTableView 
objectValueForTableColumn:(NSTableColumn *)column 
      row:(int)rowIndex 
{ 
    return [[currentCard words] objectAtIndex:rowIndex]; 
} 

currentCard является экземпляром класса GameCard, и его массив слов, является массив под вопросом. При первом запуске он работает нормально, но если я попытаюсь изменить его, то произойдет сбой.

---------- ---------- EDIT

В awakeFromNib AppController в: У меня есть этот

currentCard = [[GameCard alloc] init]; 

И в IBAction на кнопки, я есть это:

[currentCard release]; 
currentCard = [[GameCard alloc] init]; 

с зомби включен, когда я нажимаю кнопку, я получаю от этого GDB:

2009-06-22 18: 55: 03,368 2 5WordsMax [19761: 813] *** - [CFArray objectAtIndex:]: сообщение отправлено на освобожденный экземпляр 0x14ba00

ссылаясь на метод источника данных. Я пытался отслеживать ошибку памяти в течение нескольких часов, но я пропустил ее.

Я так разочарован я закомментирована каждый сохранить & релиз (без autoreleases) в коде и до сих пор получить 2009-06-22 19: 41: 58.564 25WordsMax [21765: 813] *** - [CFArray objectAtIndex:] : сообщение, отправленное на освобожденный экземпляр 0x14c330, когда я нажимаю кнопку.

И что вы называете методом источника данных? Я не звоню reloadData. Если в моем методе datasource я возвращаю @ «Word» для каждой строки, все работает нормально. В GDB я даже вижу, что мои NSLogs печатают содержимое нового массива, все без заминки. Только когда метод данных, рассматриваемый в вопросе, называется вызываемым, что возникают какие-либо проблемы.

+1

разместить код, который изменяет слова массива. Скорее всего, вы делаете ошибку управления памятью там. –

ответ

5

2009-06-22 18: 55: 03,368 25WordsMax [19761: 813] *** - [CFArray objectAtIndex]: сообщение, отправленное высвобождены например 0x14ba00

Читайте, что тщательно. Приемник был экземпляром CFArray, а селектор сообщений был objectAtIndex:.

Выделенный экземпляр был массивом, а не игровой картой.

Ваша игровая карта владеет массивом, поэтому она должна каким-то образом сохранить ее.Это означает, что вы должны:

  1. Создайте массив, используя alloc и init (и не авторезистируйте его).
  2. Сохраните его.
  3. Сделайте свою копию. (Предпочтительно, если вы получаете массив из другого объекта, как у вашего сеттера, так как полученный массив может быть изменен, и вы не хотите, чтобы другой объект мутировал «ваш» массив.)

вы синтезируете свои аксессоры, объявляете свойство как @property(retain) или @property(copy). Обратите внимание, что это не будет работать, если вы хотите изменить версию; в этом случае вам придется самостоятельно выполнить настройку.

+0

Я собираюсь вытащить свои волосы здесь. Я знаю, что мне не хватает чего-то очевидного, но независимо от того, что я делаю, не могу отследить его. У меня есть все 170 строк кода, и все равно нет кубиков. Я так расстроился, что я прокомментировал каждую запись и освобождение (без автореализаций) в коде и все еще получаю. 2009-06-22 19: 41: 58.564 25WordsMax [21765: 813] *** - [CFArray objectAtIndex:]: сообщение отправлено deallocated instance 0x14c330 , когда я нажимаю кнопку. – Walker

+0

И что вызывает метод источника данных? Я не звоню reloadData. Если в моем методе datasource я возвращаю @ «Word» для каждой строки, все работает нормально. В GDB я даже вижу, что мои NSLogs печатают содержимое нового массива, все без заминки. Только когда метод данных, рассматриваемый в вопросе, называется вызываемым, что возникают какие-либо проблемы. – Walker

+1

Сообщение на самом деле происходит от Cocoa, а не от GDB. «Я так расстроен, что я прокомментировал все, что осталось ... и все еще получаю [сообщение] ...» «Ну, да. Если вы не сохраните его, он умрет, когда сливается бассейн авторекламы. –

1

Похоже, что у вас есть ошибка подсчета ссылок, которая не будет отлаживаемой только из этого фрагмента кода. Попробуйте запустить NSZombieEnabled = 1, а затем ищите ошибки сохранения/выпуска, в которых вы управляете любым объектом, о котором вы получаете предупреждения о зомби.

+0

я включил зомби, и получил это: 2009-06-22 18: 55: 03,368 25WordsMax [19761: 813] *** - [CFArray objectAtIndex]: сообщение, отправленное высвобождены например 0x14ba00 который, кажется, проистекают из return [[currentCard words] objectAtIndex: rowIndex]; Что странно в том, что я думал, что вам нужно вызвать reloadData в tableView, прежде чем он снова вызовет этот метод источника данных, и все же мой запрос reloadData будет закомментирован. Я пытался отследить эту ошибку памяти в течение нескольких часов, но ничего не могу найти. Есть еще идеи? Спасибо – Walker

0

NSZombie сообщает вам, что объект, возвращенный из [currentCard words], где-то выпущен, вы снова используете его. Проверьте все ваши назначения на эту переменную и убедитесь, что вы не устанавливаете его для объекта с автореализацией. Затем проверьте все сообщения о выпуске и автоответчике, отправленные на него.

+1

Нет, это говорит ему, что массив выпущен где-то, а затем он снова использовал его. –

+0

Ах да. Виноват. –

0

Это может помочь увидеть метод GameCard Init и метод dealloc GameCard.

Кроме того, чтобы убедиться, что метод, который вы думаете, это проблема проблема, которую я хотел бы проверить на ноль

if([currentCard words] != nil) 
    return [[currentCard words] objectAtIndex:rowIndex]; 

else 
    return @"Blah!";