Управление памятью при копировании объектов - PullRequest
1 голос
/ 08 ноября 2011

Я знаю, что мой вопрос уже обсуждался в StackOverflow, но я нашел ответ не полным для моих нужд. Итак, вопрос:

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil];
NSMutableArray *secondArray = [[NSMutableArray alloc] init];
secondArray = [firstArray mutableCopy];

Что теперь считать для второго массива? 2 или 1? Должен ли я выпустить его дважды или только один раз? Увеличивает ли copy или mutableCopy количество сохраняемых объектов COPYING (secondArray в этом событии)?

Ответы [ 2 ]

5 голосов
/ 08 ноября 2011

Вы никогда не должны заботиться об абсолютном счете удержания. Только то, что вы «сбалансированы», это означает, что для каждых alloc, new*, copy, mutableCopy и retain вам нужны соответствующие release или autorelease (если не используется ARC, то есть).

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

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil];
NSMutableArray *secondArray = [firstArray mutableCopy];
// There is no third line.

Но давайте обсудим ваш оригинальный код и посмотрим, что произошло:

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil];
NSMutableArray *secondArray = [[NSMutableArray alloc] init];
// secondArray points to a new instance of type NSMutableArray
secondArray = [firstArray mutableCopy];
// You have copied another array (created a new NSMutableArray
// instance) and have overwritten the pointer to the old array.
// This means that the instance allocated in line 2 is still there
// (was not released) but you don't have a pointer to it any more.
// The array from line 2 has been leaked.

В Objective-C мы часто говорим о владении : очень немногие методы делают вас «владельцем» объекта. Это:

  • alloc
  • new*, как в newFoo
  • copy и mutableCopy
  • retain

Если вы вызываете их, вы получаете объект, за который вы несете ответственность . А это значит, что вам нужно позвонить на эти объекты по номеру release и / или autorelease. Например, у вас все в порядке, если вы делаете [[obj retain] retain];, а затем [[obj autorelease] release];

1 голос
/ 08 ноября 2011
NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects: obj1,obj2,nil];
NSMutableArray *secondArray = [[NSMutableArray alloc] init];
secondArray = [firstArray mutableCopy];

Что происходит, так это то, что вы создали утечку памяти. Вы просто потеряли ссылку, присвоенную secondArray, когда перезаписали ее с помощью mutableCopy of firstArray с этой строкой.

secondArray = [firstArray mutableCopy];

Если вы дважды отпустите secondArray, программа завершится сбоем, потому что вы перевыпустите изменяемый массив, назначенный

secondArray = [firstArray mutableCopy];

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

...