Как работает retainCount?

У меня проблема с retainCount

NSLog(@"%i", [self.albumReceiver retainCount]);
    self.albumReceiver = [[[FacebookAlbumsDelegateReceiver alloc] init: self] autorelease];

    NSLog(@"%i", [self.albumReceiver retainCount]);

Счетчик сохранения в первой строке равен 0, но когда он попадает в третью строку, он равен 3. Свойство self.albumReceiver является свойством retain... Но, насколько я вижу, это должно быть 2, где другие последующие счетчики хранения должны были перейти к 1, так как это было авто-релиз позже.

 NSLog(@"%i", [self.albumReceiver retainCount]);
    albumReceiver = [[[FacebookAlbumsDelegateReceiver alloc] init: self];

    NSLog(@"%i", [self.albumReceiver retainCount]);

счет сохранения начинается с 0, и в этом случае второй счет сохранения печатает 2....

Может кто-нибудь дать некоторое представление о том, как это сохранить и выпустить работу....

Я думал, что без ключевого слова "self", оно будет игнорировать вызов сеттера, не так ли? Но если я добавлю autorelease на второй пример, у меня будет ошибка.

4 ответа

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

Сказав это, объяснение того, что вы видите, заключается в следующем:

Число сохраняемых данных в первой строке равно 0

Это потому что self.albumReceiver является nil в таком случае. На реальных объектах вы никогда не увидите счет сохранения 0 (в текущей реализации Foundation).

когда доходит до третьей строки 3

Обычно вы ожидаете, что количество сохранений будет 2, +1 для alloc и +1 для назначения сохраняемого свойства. Тем не менее init: Метод может заставить некоторый другой объект сохранить его, как и метод установки для свойства. Другой объект, наблюдающий за свойством, может также сохранить объект. Короче говоря, если вы не знаете точную реализацию всех задействованных методов и точно не знаете, что KVO не используется в albumReceiver, все, что вы можете сказать о счетчике хранения, это self имеет право собственности на него (собственность NB не является исключительной, другие вещи также могут иметь право собственности). Вот почему вы не должны обращать слишком много внимания, чтобы сохранить счет.

Может кто-нибудь дать некоторое представление о том, как это сохранить и выпустить работу

Да. Вы должны думать с точки зрения собственности. Определенные методы дают вам объект, которым вы владеете. Это любой метод, начинающийся с allocлюбой метод, начинающийся с newлюбой метод, начинающийся с copy или же mutableCopy а также -retain, Если вы получаете объект любым другим способом, вы не являетесь его владельцем. Это включает в себя получение их как возвращаемый результат метода, заданные параметры метода или как справочные параметры метода или как глобальные или статические переменные.

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

Я считаю, что лучше всего думать о "вы" в вышеприведенном значении как об "объеме, в котором была объявлена ​​ссылка на объект".

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

Не использовать retainCount, (Для ситуаций, когда это целесообразно использовать, см. Этот веб-сайт.) Дополнительная информация: сообщение в блоге от bbum, предыдущая SO тема одна, вторая тема. Также обратите внимание, что retainCount устарел в последних SDK. Хорошей идеей будет обратить внимание на предупреждения об устаревании, а еще лучше - превратить все предупреждения в ошибки.

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

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

Обратите внимание на использование слов "предположительно" и "вероятно" в вышеприведенном абзаце. Я понятия не имею, действительно ли это происходит внутри платформ Cocoa/Cocoa Touch. Это проблема с использованием retainCount, у вас нет возможности узнать, какой счет должен быть в любой момент.

если ты retain объект (или создать его с именем метода, который содержит alloc, copy, mutableCopy или же new), вы release Это. Рамки свободны также retain объект, и они будут release это когда они готовы. Когда счет удержания достигнет нуля, это будет deallocредактор

Обновление: Посмотрев на исходный код GNUStep для NSObject и NSAutoreleasePool, мое возможное объяснение выше, вероятно, не в том, что происходит. Однако у меня нет возможности проверить это точно, потому что я не вижу реализации Apple этих двух объектов. Еще больше причин не доверять retainCount или любые выводы из этого.

Единственное правило, которое действительно существует в средах с ручным управлением памятью, это

Если вы используете alloc, copy, mutableCopy, new

отпустите это. В противном случае НЕ. retainCounts на самом деле не работают для отладки. Смотрите здесь

Другие вопросы по тегам