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