Когда использовать -retainCount?


Я хотел бы знать, в какой ситуации вы используете -retainCount до сих пор, и в конечном итоге проблемы, которые могут произойти, используя его.

спасибо.

11 103

11 ответов:

вы никогда не должны использовать -retainCount, потому что он никогда не скажет вам ничего полезного. Реализация фреймворков Foundation и AppKit/UIKit непрозрачна; вы не знаете, что сохраняется, почему оно сохраняется, кто его сохраняет, когда оно было сохранено и так далее.

например:

  • можно подумать, что [NSNumber numberWithInt:1] будет retainCount на 1. Это не так. Это 2.
  • можно подумать, что @"Foo" будет retainCount на 1. Оно нет. Это 1152921504606846975.
  • можно подумать, что [NSString stringWithString:@"Foo"] будет retainCount на 1. Это не так. Опять же, это 1152921504606846975.

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

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

но не используйте -retainCount. Это действительно бесполезный метод.

edit

пожалуйста, все идите вhttp://bugreport.apple.com и прошу этого -retainCount быть устаревшим. Чем больше людей попросят об этом, тем лучше.

edit #2

Как обновить,[NSNumber numberWithInt:1] теперь есть retainCount от 9223372036854775807. Если ваш код ожидал, что это будет 2, Ваш код теперь сломан.

никогда!

серьезно. Просто не делай этого.

просто следовать Руководство По Управлению Памятью и только отпустите то, что вы alloc,new или copy (или все, что вы назвали retain по первоначально).

@bbum сказал, что лучше вот на так, и еще более подробно на блог.

Autoreleased объекты-это один случай, когда проверка-retainCount неинформативна и потенциально вводит в заблуждение. Сохранить граф ничего не говорит вам о том, сколько раз -autorelease был вызван на объект и, следовательно, сколько времени он будет освобожден при нынешней autorelease пул канализацию.

Я do найти retainCounts очень полезно при проверке с помощью "инструменты".

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

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

Это никогда не подводило меня - включая поиск ошибок в ранние бета-версии iOS.

взгляните на документацию Apple по NSObject, она в значительной степени охватывает ваш вопрос: retainCount NSObject

короче говоря, retainCount, вероятно, бесполезен для вас, если вы не внедрили свою собственную систему подсчета ссылок (и я могу почти гарантировать, что у вас ее не будет).

по собственным словам Apple, retainCount "обычно не имеет значения при отладке проблем управления памятью".

какие проблемы вы можете получить от его использования? Все, что он делает, это возвращает счетчик сохранения объекта. Я никогда не называл его и не могу придумать ни одной причины, по которой я бы это сделал. Я переопределил его в синглтонах, чтобы убедиться, что они не освобождены.

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

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

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

попробуйте написать правильный код, например, если вы создаете объект с помощью alloc и т. д., а затем убедитесь, что вы его правильно отпустите.

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

в ваших усилиях, чтобы сделать вашу точку зрения вы серьезно завышены непостижимая природа ценности. Это правда, что это не всегда счетчик ссылок. Есть некоторые специальные значения, которые используются для флагов, например, чтобы указать, что объект никогда не должен быть освобожден. Число, подобное 1152921504606846975, выглядит очень загадочным, пока вы не напишете его в hex и не получите 0xfffffffffffffff. И 9223372036854775807 - это 0x7fffffffffffffff в шестнадцатеричном формате. И это действительно не так удивительно, что кто-то решил бы использовать такие значения в качестве флагов, учитывая, что это будет потребуется почти 3000 лет, чтобы получить количество удерживаемых до большего числа, предполагая, что вы увеличили количество удерживаемых 100 000 000 раз в секунду.

вы никогда не должны использовать его в своем коде, но это может определенно помочь при отладке

никогда не используйте -retainCount в коде. Однако, если вы используете, вы никогда не увидите, что он возвращает ноль. Думаю о том, почему. : -)

примеры, используемые в сообщении Дэйва являются NSNumber и NSStrings...so, если вы используете некоторые другие классы, такие как UIViews, я уверен, что вы получите правильный ответ(счет сохранения зависит от реализации, и это предсказуемо).