сохранить граф NSArray против NSMutableArray - PullRequest
2 голосов
/ 19 апреля 2011

Краткий вопрос с примером кода:

NSLog(@"%i", [[[NSArray alloc] init] retainCount]);
NSLog(@"%i", [[[NSMutableArray alloc] init] retainCount]);

Вывод:

2
1

Почему значения retainCount из NSArray и NSMutableArray отличаются?

Ответы [ 2 ]

10 голосов
/ 19 апреля 2011

Никто за пределами Apple не знает наверняка (но я уверен, что скоро найдется кто-то, кто утверждает, что он точно знает, почему это произошло).
Возможно, это происходит потому, что iOS умна и использует пустые NSArrays. И, очевидно, [[NSArray alloc] init] создает пустой массив, который бесполезен. И поскольку он не изменчив (т.е. вы не можете добавлять объекты позже, и он будет пустым всегда), все пустые указатели NSArrays могут ссылаться на один и тот же объект.

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


Не используйте retainCount!

Из яблочной документации :

Важно : Этот метод обычно не имеет значения при отладке проблем управления памятью. Поскольку любое количество объектов каркаса могло сохранить объект для хранения ссылок на него, в то время как пулы автоматического выпуска могут содержать любое количество отложенных выпусков для объекта, маловероятно, что вы можете получить полезную информацию из этого метод.

Чтобы понять основные правила управления памятью, которые вы должны соблюдать, прочитайте « Правила управления памятью ». Для диагностики проблем управления памятью используйте подходящий инструмент:

  • Статический анализатор LLVM / Clang обычно может обнаруживать проблемы с управлением памятью даже до запуска вашей программы.
  • Инструмент Object Alloc в приложении Instruments (см. Руководство пользователя Instruments ) может отслеживать распределение и уничтожение объектов.
  • Shark (см. Руководство пользователя Shark ) также профилирует распределение памяти (среди множества других аспектов вашей программы).
6 голосов
/ 19 апреля 2011

Причина в том, что [[NSArray alloc] init] возвращает один и тот же объект независимо от того, сколько раз вы его вызываете.Посмотрите на этот код:

NSArray *array1 = [[NSArray alloc] init];
NSArray *array2 = [[NSArray alloc] init];
NSArray *array3 = [[NSArray alloc] init];
NSLog(@"\narray1: %p\narray2: %p\narray3: %p",
      array1, array2, array3);

Вывод:

array1: 0x10010cae0
array2: 0x10010cae0
array3: 0x10010cae0

Это имеет смысл, поскольку NSArray является неизменным, а все пустые массивы идентичны.Похоже, NSArray поддерживает пустой массив для этой цели, поскольку счетчик сохранения для массива, на который указывают array1, array2 и array3, равен 4.

Я не согласен с ответом @ fluchtpunkt, но думаюможно с уверенностью сказать, что мы точно знаем, почему это происходит.Полагаю, вы могли бы сказать, что никто точно не знает, почему Apple решила реализовать его таким образом, но это кажется хорошей идеей.

...