Я должен сохранить NSMutableArray, хотя это свойство - PullRequest
0 голосов
/ 15 ноября 2010

Я новичок, но я много читал об управлении памятью и действительно пытался найти ответ сам. Это звучит так просто, и все же я, очевидно, не понимаю. У меня есть NSMutableArray как свойство в .h:

@property (nonatomic, retain) NSMutableArray *documentListArray;

Я синтезирую это и освобождаю его в (void) dealloc. Чтобы заполнить массив, у меня есть метод - (void) updateRecordList и там:

self.documentListArray=[DocumentDatabase getDocumentListSortedByDate];

РЕДАКТИРОВАТЬ: следующая строка:

[[self recordListTableView] reloadData];

где DocumentDatabase - это другой класс с методами класса getDocumentListSortedByDate и getDocumentList. Вот что происходит в getDocumentListSortedByDate:

NSMutableArray *returnArray = [DocumentDatabase getDocumentList];
//sorting...
NSLog("array count:%i",[returnArray count]); //returns correct numbers first and second time
return returnArray;

и в getDocumentList

NSMutableArray *returnArray = [NSMutableArray arrayWithCapacity:files.count];
//add file data to array...
return returnArray;

Это работает при первом вызове updateRecordList, но после добавления файла и повторного вызова updateRecordList происходит сбой (с использованием NSZombies): * - [NSCFNumber dealloc]: сообщение отправлено освобожденному экземпляру 0x7504c90. С большим количеством регистрации я сузил проблему до строки выше в updateRecordList, и это работает, если я изменяю это на:

self.documentListArray=[[DocumentDatabase getDocumentListSortedByDate] retain];

Мой вывод заключается в том, что массив в getDocumentList был автоматически освобожден до его поступления. Итак, мои вопросы:
1. Почему я должен сохранить это там? Разве это не должно произойти само по себе, объявив собственность (сохранить)? Или, другими словами, почему массив автоматически освобождается слишком рано (при условии, что это то, что происходит)?
2. Когда я присваиваю новый массив self.documentListArray, автоматически ли освобождается старый массив? Если я попытаюсь выпустить его самостоятельно, прежде чем получить новый documentList, он тоже вылетит.

Заранее спасибо за любой ответ.

EDIT: Может быть, я идиот: я не упомянул, что documentListArray является источником данных для UITableView (см. Добавленную строку сверху). Я подозреваю, что я делаю что-то не так с заполнением табличного представления, и массив сохраняется ...? Однако происходит сбой при назначении свойства, а не при reloadData. Я возвращаюсь, чтобы изучить, правильно ли я использую протокол UITableViewDataSource. Спасибо всем, ваши ответы привели меня на правильный путь. Обновится, когда решится.

EDIT2: Теперь он работает без сохранения, и я думаю, что понимаю почему: я много отлаживал и обнаружил, что объекты, содержащиеся в объектах, добавлены в массив, где nil. В частности, глубоко в encodeWithCoder я не использовал «self» при присваивании значений. При декодировании те значения, где ноль. Так как я изменил это, похоже, работает. Я подозреваю , что не назначение нового массива вызвало сбой, но TableView, который будет читать новый массив, даже прежде чем я вызову reloadData. Что привело бы к вопросу Дэвидса о синхронном доступе. Спасибо всем за помощь.

1 Ответ

1 голос
/ 15 ноября 2010
  1. Код, который вы показали, кажется правильным; не нужно (или корректно) вызывать retain самостоятельно, если вы присваиваете значение свойству с семантикой retain до того, как пул авто-выпуска будет очищен Все вызовы (getDocumentListSortedByDate, getDocumentList) происходят синхронно, или вы делаете это в фоновом режиме? Дважды проверьте, что вы назначаете, используя «Я». ("self.documentListArray =") вместо простого назначения непосредственно экземпляру var ("documentListArray ="); если вы опустите «self», сеттер будет обойден.

  2. Нет, не освобождайте старое значение перед присвоением; это работа сеттера.

...