NSMutableArray управление памятью - PullRequest
24 голосов
/ 19 января 2009
NSMutableArray *a1 = [[NSMutableArray alloc] init];
NSMutableArray *a2 = [NSMutableArray array];

TempObj *obj = [[TempObj alloc] init]; //assume this line is repeated for each obj
[a1 addObject:obj];
[a1 addObject:obj2];
[a1 addObject:obj3];
[a1 addObject:obj4];

[obj release];
[obj2 release];
[obj3 release];
[obj4 release];

[a1 release];

Ладно, a2 - это объект autorelease, поэтому мне не нужно вызывать release? Кроме того, как вы узнаете, когда получаете объект автоматического выпуска?

А для a1 мне не нужно перебирать массив и сначала освобождать каждый объект? Что если бы я позвонил [a1 removeAllObjects]; это вызывает [[a1 objectAtIndex: #] release];

Должен ли я освобождать эти объекты после добавления их в массив?

Ответы [ 5 ]

45 голосов
/ 19 января 2009

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

Что касается autorelease vs release, то единственный способ узнать наверняка (кроме возможного чтения документации) - по названию метода. В целом, я считаю, что если вы не выделяете объект, вы не несете ответственности за его освобождение.

Что касается методов создания объектов, все вспомогательные методы (array:, arrayWithObjects:, arrayWithArray: и т. Д.) Возвращают автоматически выпущенные объекты. Однако соответствующие им методы init (init:, initWithObjects:, initWithArray: и т. Д.) Этого не делают - если вы их вызываете, вы отвечаете за вызов release для возвращаемого объекта.

Кажется, я вспомнил еще несколько вопросов на эту тему здесь - вы можете попытаться найти более подробное объяснение.

12 голосов
/ 19 января 2009

Об управлении памятью в Objective-C проще думать как о владении , а не как о сохраняемой версии. Когда вы добавляете объекты в массив, массив становится совладельцем объекта и отвечает за правильное управление памятью. Когда владелец (независимо от того, какой объект содержит код, который вы разместили) вызывает release для объектов, он отказывается от владения, и теперь массив является единственным владельцем.

Apple хорошо знакома с принципами владения в Какао (включая то, как вы знаете, когда отвечаете за вызов release объекта): Руководство по программированию управления памятью для какао . Обязательно прочитайте, если хотите использовать Какао.

0 голосов
/ 24 ноября 2010

Вы выпустили obj, obj2, obj3, obj4 сразу после добавления их в массив (лучший способ). В противном случае вам пришлось бы зациклить и освободить каждый объект (это глупый путь: тот, который я делал до сих пор).

0 голосов
/ 20 мая 2010

я не знаю, прав я или нет

NSMutableArray *a1 = [[NSMutableArray alloc] init]; // will be autorelease
NSMutableArray *a1 = [NSMutableArray alloc]; // will not autorelease

после вас [a1 removeAllObjects];

0 голосов
/ 19 января 2009

Основное, что нужно запомнить, это: вы должны балансировать каждый вызов «init», «retain» или «copy» с соответствующим вызовом «release» или «autorelease». Это действительно все, что вам нужно знать.

В вашем примере a1 вызывал «init», поэтому вам нужно иметь «release» где-то на нем. То же самое с "obj". Вы не вызывали «init», «retain» или «copy» для чего-либо еще, поэтому вам не нужно вызывать «release» или «autorelease» для чего-либо еще.

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