Основна проблема, пов’язана з пам’яттю, яку ви все ще повинні знати, - це збереження циклів. Це відбувається, коли один об’єкт має сильний вказівник на інший, але цільовий об'єкт має сильний покажчик назад до оригіналу. Навіть коли всі інші посилання на ці об’єкти будуть видалені, вони все одно будуть триматися один за одного і не будуть випущені. Це також може статися опосередковано ланцюжком об'єктів, у якого може бути останній ланцюг, що посилається на попередній об'єкт.
Саме з цієї причини існують __unsafe_unretained
і __weak
кваліфікаційні права власності. Перший не збереже жодного об'єкта, на який він вказує, але залишає відкритим можливість того, що цей об’єкт відходить, і він вказує на погану пам'ять, тоді як другий не зберігає об'єкт і автоматично встановлює нуль, коли його ціль розміщена. З двох, __weak
як правило, переважніше на платформах, які його підтримують.
Ви б використовували ці класифікатори для таких речей, як делегати, де ви не хочете, щоб об'єкт зберігав свого делегата і потенційно призводив до циклу.
Ще одна значна проблема, пов'язана з пам'яттю, - це обробка об'єктів Core Foundation та пам'яті, виділених за допомогою malloc()
таких типів char*
. ARC не керує цими типами, а лише об'єктами Objective-C, тому вам все одно доведеться з ними боротися самостійно. Типи основних фондів можуть бути особливо складними, оскільки іноді їх потрібно переадресувати, щоб вони відповідали об'єктам Objective-C, і навпаки. Це означає, що управління потрібно переносити назад та назад від АРК при з'єднанні між типами CF та Objective-C. Додано кілька ключових слів, пов’язаних із цим з'єднанням, і Майк Еш має чудовий опис різних мостинкових справ у своєму тривалому написанні ARC .
Окрім цього, є ще кілька менш частих, але все ще потенційно проблемних випадків, які опублікована специфікація детально описується.
Значна частина нової поведінки, заснованої на утриманні об'єктів довкола, доки на них є сильний покажчик, дуже схожа на збирання сміття на Mac. Однак технічні основи дуже різні. Цей стиль управління пам’яттю замість того, щоб проводити процес збирання сміття, який проходить через регулярні проміжки часу, щоб очистити об'єкти, на які вже не вказували, цей стиль управління пам’яттю покладається на жорсткі правила збереження / випуску, яких нам потрібно дотримуватися в Objective-C.
ARC просто приймає повторювані завдання управління пам’яттю, які ми мали виконувати роками, і завантажує їх у компілятор, тому нам більше не доведеться турбуватися про них знову. Таким чином, у вас не виникає проблем із зупинкою чи профілями пам'яті, що виникають на платформах, зібраних сміттям. Я пережив це обоє у своїх зібраних сміттям додатках для Mac, і нетерпляче бачу, як вони поводяться під ARC.
Докладніше про збирання сміття проти ARC дивіться у цій дуже цікавій відповіді Кріса Леттнера у списку розсилки Objective-C , де він перераховує багато переваг ARC над збиранням сміття Objective-C 2.0. Я зіткнувся з кількома проблемами GC, які він описує.