Мені хотілося б дізнатися, в якій ситуації ви використовували до -retainCount
цього часу, і врешті-решт проблеми, які можуть трапитися з його використанням.
Дякую.
Мені хотілося б дізнатися, в якій ситуації ви використовували до -retainCount
цього часу, і врешті-решт проблеми, які можуть трапитися з його використанням.
Дякую.
Відповіді:
Ніколи не слід користуватися -retainCount
, тому що це ніколи не говорить вам нічого корисного. Реалізація рамок Foundation та AppKit / UIKit є непрозорою; ви не знаєте, що зберігається, чому він зберігається, хто його зберігає, коли він зберігається тощо.
Наприклад:
[NSNumber numberWithInt:1]
було б retainCount
1. Це не так. Це 2.@"Foo"
було б retainCount
1. Це не так. Це 1152921504606846975.[NSString stringWithString:@"Foo"]
було б retainCount
1. Це не так. Знову ж таки, це 1152921504606846975.В основному, оскільки що-небудь може зберегти об'єкт (і, отже, змінити його retainCount
), і оскільки у вас немає джерела більшості коду, який запускає додаток, об'єкт retainCount
безглуздий.
Якщо ви намагаєтеся відстежити, чому об’єкт не розміщується, скористайтеся інструментом "Витоки" в "Інструменти". Якщо ви намагаєтеся відстежити, чому об’єкт був розміщений занадто рано, скористайтеся інструментом Zombies в інструментах.
Але не використовуйте -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
можна отримати (набагато детальніше) від інструментів та її інструментів.
retain
, retain
, retain
, autorelease,
autorelease, autorelease
може бути абсолютно дійсним результатом проходження об'єкта через UIKit API, наприклад.
Автомобільні об'єкти - один із випадків, коли перевірка -retainCount є неінформативною та потенційно оманливою. Кількість збережених даних нічого не говорить про те, скільки разів викликали автоматичний випуск на об’єкт, а отже, скільки часу він буде випущений, коли поточний пул автовипуску зливається.
Я дійсно знайти retainCounts дуже корисні при перевірці з допомогою «Інструменти».
За допомогою інструменту "виділення" переконайтесь, що "Записати довідкові підрахунки" увімкнено, і ви можете зайти в будь-який об'єкт і переглянути його історію retainCount.
Шляхом спарювання алоків та релізів ви можете добре уявити, що відбувається, і часто вирішувати ті складні випадки, коли щось не випускається.
Це ніколи мене не підводило - включаючи пошук помилок у ранніх бета-версіях iOS.
Погляньте на документацію Apple на NSObject, вона в значній мірі охоплює ваше питання: NSObject retainCount
Коротше кажучи, retainCount, ймовірно, марний для вас, якщо ви не впровадили власну систему підрахунку довідок (і я майже можу гарантувати, що у вас її не буде).
За власними словами Apple, функція retainCount "зазвичай не має значення при налагодженні проблем управління пам'яттю".
Звичайно, ви ніколи не повинні використовувати метод retainCount у своєму коді, оскільки значення його значення залежить від того, скільки авторелізів було застосовано до об'єкта, і це те, що ви не можете передбачити. Однак це дуже корисно для налагодження - особливо коли ви знижуєте витоки пам’яті в коді, який викликає методи об’єктів Appkit поза основним циклом подій - і його не слід заставляти.
Намагаючись висловити свою думку, ви серйозно завищили непереборний характер цінності. Це правда, що це не завжди підрахунок. Існують деякі спеціальні значення, які використовуються для прапорів, наприклад, щоб вказати, що об'єкт ніколи не повинен бути розміщений. Таке число, як 1152921504606846975, виглядає дуже таємничим, поки ви не напишете його шістнадцятком і не отримаєте 0xfffffffffffffffff. І 9223372036854775807 - це 0x7fffffffffffffffff у шістнадцятковій кількості. І це насправді не так дивно, що хтось вирішив би використовувати такі значення, як ці, як прапори, враховуючи, що знадобиться майже 3000 років, щоб утриматиКайт вийшов більшим, ніж більша кількість, якщо припустити, що ви збільшили утримувану кількість 100 000 000 разів на секунду.
Які проблеми можна отримати від його використання? Все, що він робить - це повернути нерозподілений рахунок об'єкта. Я ніколи цього не називав і не можу придумати будь-якої причини, яку я хотів би. Я відмінив це в одиночних клавішах, щоб переконатися, що вони не розташовані.
retainCount
для управління пам'яттю.
Ви не повинні турбуватися про витоку пам’яті, поки ваша програма не працює і не зробить щось корисне.
Як тільки це станеться, запустіть інструменти та скористайтеся програмою і перевірте, чи справді відбувається витік пам'яті. У більшості випадків ви створили об'єкт самостійно (таким чином ви володієте ним) і забули випустити його після того, як ви закінчили.
Не намагайтесь оптимізувати свій код під час написання, ваші здогадки про те, що може просочитися в пам'яті або зайняти занадто довго, часто помиляються, коли ви фактично використовуєте додаток.
Спробуйте записати правильний код, наприклад, якщо ви створюєте об'єкт за допомогою alloc та подібного, тоді переконайтеся, що ви правильно його звільнили.
-retainCount
.