2011-09-27 2 views
1

Если у меня есть переменная, на мой взгляд контроллераObjective-C вопрос простой памяти

viewcontroller.m

@interface MemoryTestViewController : UIViewController 
{ 
    NSMutableArray *array; 
} 

@end 

в моей реализации

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    NSMutableArray *aux = [[NSMutableArray alloc] initWithCapacity:1]; 
    array = aux; 
    [aux release]; 
    // Do i have to do array release? 
} 

Должен ли я освободить свою переменную массив где-то? Теоретически я havent выделил эту переменную ... Я тестирую утечку памяти, и даже если я ничего не выпущу, инструменты не обнаружат утечки.

ответ

3

Нет, вам не нужно освободить. Все, что вам нужно, - назначить указатель aux на вашу переменную array. array недействителен в тот момент, когда вы отпускаете aux. Возможно, это не так. Если вы хотите работать с array, вам придется сохранить его.

+0

Что произойдет, если у меня есть что-то вроде NSString * name = [[NSString alloc] ...], а затем снова сделаю name = [[NSString alloc ] ...] Должен ли я освободить его перед повторным назначением? –

+0

Да. В противном случае вы выделили бы память для первой строки, но заменили бы вашу ссылку на блок выделенной памяти, поэтому вы не сможете ее позднее выпустить. Вы должны использовать Google для «управления памятью ios» и читать руководства Apple. Все будет проще с iOS5, у которого есть автоматический подсчет ссылок. – Krumelur

+0

Могу ли я сделать что-то вроде [name initWithString: ...] после первого выделения? –

0

Вы должны добавить свойство:

@property (неатомической, сохранить) NSMutableArray * массив;

, а затем в вашем viewDidLoad:

// неправильно, протечек: self.array = [[NSMutableArray Alloc] initWithCapacity: 1];

array = [[NSMutableArray alloc] initWithCapacity: 1];

и да, несколько позже выпустить его, вероятно, в dealloc ..

+0

Это утверждение 'self.array = [[NSMutableArray alloc] initWithCapacity: 1];' утечки. Это должно быть 'self.array = [[[NSMutableArray alloc] initWithCapacity: 1] autorelease];'. Автореклама балансирует alloc-init, а средство настройки свойств сохраняет объект, который сбалансирован соответствующим выпуском в dealloc. – albertamg

+0

Я написал «... позже выпустил его». –

+1

Выполняя это, у вас нет ссылки, через которую вы _can_ отпустите ее позже (строго говоря, это возможно «[self.array release]» сразу после этого, но это действительно ужасный запах кода. как правило, имеют один указатель на каждый из них - IOW, один _reference_ для каждого _reference count_./cc @albertamg –

0

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

alloc поднял сохранить счетчик и [aux release] установить его

+3

'alloc' дает объекту значение удержания 1, _not_' init. ..' –

+0

Спасибо, ребята !!!!!! –

+0

Справа. Спасибо, Джош. –

3

Вы уже выпустили массив с [aux release]; - у вас на самом деле есть противоположная проблема с утечкой: перевыпуск.

Назначения в Objective-C - это просто назначения указателей; нет копирования или автоматического копирования memory management. Когда вы говорите array = aux;, array теперь указывает на тот же объект, что и aux. Если затем избавиться от aux, освободив его (и, следовательно, позволяя ему быть высвобождены), array не указывает ни на что больше *

У вас есть несколько вариантов для фиксации этого:.

  1. (Простейшие) Присвоить вновь созданный массив непосредственно array:

    array = [[NSMutableArray alloc] initWithCapacity:1];

    Это дает вам право собственности на новый массив под названием array. Не отпускайте его, пока вы не закончите с ним (возможно, в dealloc, конечно, не в этом методе).

  2. (Best) Создание declared property для array и пусть этот механизм обработки управления памятью для вас:


@interface MemoryTestViewController : UIViewController 
{ 
    NSMutableArray *array; 
} 

@property (copy, nonatomic, setter=setArrayByMutableCopy) NSMutableArray * array; 
@end 

@implementation MemoryTestViewController 
@synthesize array; 

// Properties can't automatically make mutable copies, so you need to create 
// your own setter method. 
- (void) setArrayByMutableCopy: (NSMutableArray *)newArray { 
    NSMutableArray * tmp = [newArray mutableCopy]; 
    [array release]; 
    array = tmp; 
} 
... 

* Или, скорее, он указывает на место, где раньше было действительный объект, который является отличным способом сделать вашу программу аварийной.

Смежные вопросы