Когда использовать -retainCount?
Я хотел бы знать, в какой ситуации вы использовали -retainCount
пока что, и в конечном итоге проблемы, которые могут возникнуть при его использовании.
Благодарю.
11 ответов
Вы никогда не должны использовать -retainCount
потому что это никогда не говорит вам ничего полезного. Реализация платформ Foundation и AppKit/UIKit непрозрачна; вы не знаете, что хранится, почему оно сохраняется, кто его хранит, когда оно сохраняется и так далее.
Например:
- Вы думаете, что
[NSNumber numberWithInt:1]
будет иметьretainCount
из 1. Это не так. Это 2 - Вы думаете, что
@"Foo"
будет иметьretainCount
из 1. Это не так. Это 1152921504606846975. - Вы думаете, что
[NSString stringWithString:@"Foo"]
будет иметьretainCount
из 1. Это не так. Опять же, это 1152921504606846975.
По сути, поскольку все может сохранить объект (и, следовательно, изменить его retainCount
), и поскольку у вас нет источника большей части кода, который запускает приложение, объект retainCount
бессмысленно.
Если вы пытаетесь выяснить, почему объект не освобождается, используйте инструмент "Утечки" в инструментах. Если вы пытаетесь выяснить, почему объект был освобожден слишком рано, используйте инструмент "Зомби" в разделе "Инструменты".
Но не используйте -retainCount
, Это действительно бесполезный метод.
редактировать
Пожалуйста, все перейдите на http://bugreport.apple.com/ и попросите, чтобы -retainCount
быть устаревшим. Чем больше людей просят об этом, тем лучше.
редактировать № 2
Как обновление,[NSNumber numberWithInt:1]
теперь имеет retainCount
of 9223372036854775807. Если ваш код ожидал, что он будет равен 2, ваш код теперь поврежден.
НИКОГДА!
Шутки в сторону. Просто не делай этого.
Просто следуйте рекомендациям по управлению памятью и выпускайте только то, что вы alloc
, new
или же copy
(или все, что вы назвали retain
по факту).
@bbum сказал это лучше всего здесь на SO, и даже более подробно в своем блоге.
Автоматически освобожденные объекты являются одним из случаев, когда проверка -retainCount неинформативна и может вводить в заблуждение. Подсчет сохранения ничего не говорит вам о том, сколько раз -autorelease вызывался для объекта и, следовательно, сколько раз он будет освобожден, когда текущий пул авто-выпуска истощится.
Я считаю retainCounts очень полезным при проверке с помощью "Инструментов".
Используя инструмент "распределения", убедитесь, что "Счетчик ссылок на записи" включен, и вы можете перейти к любому объекту и просмотреть его историю retainCount.
Сопрягая выпуски и выпуски, вы можете получить хорошее представление о том, что происходит, и часто решать те сложные случаи, когда что-то не выпускается.
Это никогда не подводило меня - включая поиск ошибок в ранних бета-версиях iOS.
Взгляните на документацию Apple по NSObject, она в значительной степени охватывает ваш вопрос: NSObject retainCount
Короче говоря, retainCount, вероятно, бесполезен для вас, если вы не внедрили свою собственную систему подсчета ссылок (и я почти гарантирую, что у вас ее не будет).
По словам самого Apple, retainCount "обычно не имеет значения при отладке проблем управления памятью".
Конечно, вы никогда не должны использовать метод retainCount в своем коде, поскольку значение его значения зависит от того, сколько авторелизов было применено к объекту, и это то, что вы не можете предсказать. Однако это очень полезно для отладки - особенно, когда вы выслеживаете утечки памяти в коде, который вызывает методы объектов Appkit вне основного цикла обработки событий - и это не следует считать устаревшим.
В своих попытках выразить свою точку зрения вы серьезно преувеличили непостижимый характер ценности. Это правда, что это не всегда счетчик ссылок. Есть некоторые специальные значения, которые используются для флагов, например, чтобы указать, что объект никогда не должен быть освобожден. Число вроде 1152921504606846975 выглядит очень загадочно, пока вы не напишите его в шестнадцатеричном виде и не получите 0xfffffffffffffff. И 9223372036854775807 - это 0x7fffffffffffffff в шестнадцатеричном формате. И на самом деле неудивительно, что кто-то выбрал бы использование таких значений в качестве флагов, учитывая, что для получения retainCount потребуется больше 3000 лет, чем для большего числа, при условии, что вы увеличили retainCount 100 000 000 раз в секунду.
Вам не следует беспокоиться об утечке памяти, пока ваше приложение не заработает и не сделает что-то полезное.
Как только это произойдет, запустите инструменты и используйте приложение и посмотрите, действительно ли происходят утечки памяти. В большинстве случаев вы сами создали объект (таким образом, вы им владеете) и забыли отпустить его после того, как закончили.
Не пытайтесь оптимизировать ваш код во время его написания, ваши предположения о том, что может привести к утечке памяти или слишком долгому времени, часто бывают ошибочными, когда вы действительно используете приложение в обычном режиме.
Попробуйте написать правильный код, например, если вы создаете объект с использованием alloc и тому подобного, то убедитесь, что вы его правильно выполнили.
Какие проблемы вы можете получить от его использования? Все, что он делает, это возвращает счет сохранения объекта. Я никогда не звонил и не могу придумать ни одной причины, по которой я бы это сделал. Я переопределил это в синглетонах, чтобы убедиться, что они не освобождены.
Никогда не используйте -retainCount в вашем коде. Однако, если вы используете, вы никогда не увидите, что он возвращает ноль. Подумай почему.:-)
Примеры, использованные в посте Дэйва, - это NSNumber и NSStrings... так что, если вы используете некоторые другие классы, такие как UIViews, я уверен, что вы получите правильный ответ (счет сохранения зависит от реализации, и это предсказуемо).
Вы никогда не должны использовать это в своем коде, но это может определенно помочь при отладке