Я все еще не получил полную картину, прочитав все ответы выше. Непрофессиональное упражнение, которое я выполнил ниже, наконец помогло мне понять, что происходит. Просто поместите это на тот случай, если это поможет другим новичкам.
Предположим, у вас есть следующие
@interface Class X
-(void) methodX:(NSMutableArray *)array;
@end
В какой-то другой части кода у вас есть следующая последовательность
ClassX *objectX = [[ClassX alloc] init];
NSMutableArray *arrayXX = [@[@(1), @(2)] mutableCopy];
//What is stored in arrayXX is the address in the heap at which the NSMutableArray object starts, lets call this address ZZZ
//array starting at address ZZZ in the heap now contains NSNUmbers @1,@2
[objectX methodX:array]
Когда вы вызываете [objectX methodX:array]
, метод получает копию из array
. Так как массив содержит адрес (то есть указатель), копия является особенной в том, что то, что получено, является другой переменной с адресом ZZZ в нем.
Итак, если methodX делает [array removeObjectAtIndex:0]
, то объект, начинающийся с адреса ZZZ, будет затронут (теперь содержит только один NSNUmber @ (2)). Поэтому, когда метод возвращается, исходный массив также затрагивается.
Предположим, что вместо methodX выполняется array = [@[@(2)] mutableCopy];
, тогда на исходный массив это не влияет. Это потому, что вы не пошли в адрес ZZZ и что-то изменили. Вместо этого вы перезаписали ZZZ в копии , полученной методом, на другой адрес YYY. Адрес YYY - это начало объекта NSMUtableArray с одним элементом NSNUmber @ (2). Исходный адрес ZZZ по-прежнему содержит NSMUtableArray с двумя элементами. @ (1) и @ (2). Таким образом, при возврате метода исходный массив не изменяется.