Может ли переменная bu использоваться во второй раз после освобождения? - PullRequest
1 голос
/ 11 апреля 2010

Я пытаюсь понять управление памятью в ObjectiveC, и все же некоторые вещи для меня беда. У меня есть переменная экземпляра:

    NSMutableArray *postResultsArray;

при нажатии кнопки в пользовательском интерфейсе я создаю новый массив:

self.postResultsArray = [NSMutableArray array];

Затем я добавляю несколько объектов в массив, и когда вся операция завершена, я хотел бы освободить массив:

[self.postResultsArray release];

(я предполагаю, что все объекты, хранящиеся в массиве, будут освобождены вместе с массивом). Проблема появляется, когда я снова нажимаю кнопку и в коде хочу снова создать массив с:

self.postResultsArray = [NSMutableArray array];

Я получаю:

[выпуск CFArray]: сообщение отправлено освобожденному экземпляру 0x3d9e390

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

Спасибо!

Ответы [ 4 ]

2 голосов
/ 11 апреля 2010

Не делайте этого:

[self.postResultsArray release];

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

[postResultsArray release];
postResultsArray = nil;

или

self.postResultsArray = nil;

Что происходит, так это код для настройкиpostResultsArray выглядит следующим образом (перефразируя, не точно):

-(void)setPostResultsArray:(NSMutableArray *)newArray {
    [array retain];
    [postResultsArray release]; // this is what's causing the the deallocation message in your log
    postResultsArray = array;
}
1 голос
/ 11 апреля 2010

Не следует вручную освобождать объект, доступ к которому осуществляется через свойство.Вместо

[self.postResultsArray release];

делай

self.postResultsArray = nil;

и все будет хорошо.Сеттер освободит старый массив и назначит указателю nil.Сейчас происходит следующее: установщик пытается освободить старый массив, когда вы присваиваете новый массив свойству, но вы уже освободили этот массив, поэтому возникает ошибка.

0 голосов
/ 11 апреля 2010

Вы должны вызывать release только в том случае, если вы создаете объект с одним из сообщений «init» или явно вызываете retain самостоятельно. Поскольку вы не делаете ни того, ни другого, вам не нужно вызывать release, поскольку код, создавший массив, будет обрабатывать релиз - скорее всего, с помощью autorelease.

0 голосов
/ 11 апреля 2010

Не делай [self.postResultsArray release];, делай self.postResultsArray = nil, это связано с реализацией свойств. Они автоматически разблокируют все, что в данный момент хранится, и сохраняют новое значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...