Вы никогда не должны заботиться об абсолютном счете удержания. Только то, что вы «сбалансированы», это означает, что для каждых 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];