Призначення та функції механізму ARC - Блог веб-програміста
При створенні нового проекту та виборі шаблону програми у середовищі Xcode 5 для цього проекту за замовчуванням застосовується механізм ARC. Це, серед іншого, означає таке.
- Параметр Objective-C Automatic Reference Counting (clang_enable_objc_arc) налаштування режиму побудови в компіляторі LLVM набуває логічного значення YES.
- Оператори retain або release відсутні у файлах шаблону проекту із розширенням .т.
- Будь-який код, що автоматично вводиться згодом у середовищі Xcode, наприклад, при формуванні властивості шляхом перетягування при натиснутій клавіші з nib-файлу в прикладний код, відповідає угодам, прийнятим у механізмі ARC.
Існуючий проект, що не підтримує механізм ARC, можна також привести у відповідність до цього механізму. З цією метою виберіть у середовищі Xcode команду меню Edit^RefactorOConvert to Objective-C ARC, яка допоможе внести необхідні зміни до коду. Приймати механізм ARC для проекту зовсім не обов'язково. Так, якщо є старий код, несумісний з механізмом ARC і, можливо, написаний кимось іншим, його, можливо, потрібно впровадити в проект, що підтримує механізм ARC, не вносячи істотних змін до коду, несумісного з цим механізмом. Для цього зосередьте весь код, несумісний з механізмом ARC, в окремих файлах та для кожного з цих файлів відредагуйте ціль, перейдіть на вкладку Build Phases (Стадії побудови), двічі клацніть на лістингу з файлу з кодом, несумісним з механізмом ARC, у розділі Compile Sources і наберіть -fno-objc-arc у текстовому полі, щоб ввести цю директиву в стовпець Compiler Flags.
Механізм ARC вставляє команди retain та release на двох стадіях.
- Механізм ARC поводиться дуже консервативно і за найменшого сумнівузберігає, а потім звільняє об'єкти з пам'яті. Фактично, цей механізм зберігає об'єкти при будь-якому збігу обставин, що може мати найменші наслідки управління пам'яттю. Зокрема, він зберігає об'єкт, коли останній передається як аргумент, присвоюється змінною тощо. Він може навіть вставляти тимчасові змінні, щоб досить рано звернутися до об'єкта та мати можливість зберегти його. Але, звісно, він і звільняє об'єкт узгоджено. Це означає, що після завершення кожної стадії управління пам'яттю відбувається технічно коректно. Один об'єкт може зберігатися і звільнятися набагато частіше, ніж при використанні команд retain і release вручну, але, принаймні, можна бути впевненим у тому, що вивісні покажчики та витоку об'єктів з пам'яті не виникнуть.
- Механізм ARC виконує оптимізацію, видаляючи стільки пар команд retain і release з кожного об'єкта, скільки можна, забезпечуючи водночас надійність з погляду фактичної поведінки програми. Це означає, що після завершення другої стадії управління пам'яттю, як і раніше, відбувається не тільки технічно коректно, але й ефективно.
Розглянемо як приклад наступний код:
Для виконання цього фрагмента коду додатковий код керування пам'яттю насправді не потрібний з причин, що розглядаються в наступному розділі. Навіть якщо не застосовувати механізм ARC, то вводити команди retain та release у цей код не потрібно. Але неважко уявити, що на першій стадії виконання цього коду механізм ARC буде діяти досить консервативно, гарантуючи, що змінна буде мати порожнє значення nil або ж вказувати на об'єкт, зберігаючи кожне значення, що присвоюється їй, і в той же час звільняючи кожне присвоєне їй раніше значення, на якевона вказувала, за умови, що це значення було раніше збережено за його присвоєння даної змінної. Таким чином, неважко уявити, хоча це навряд чи буде абсолютно правильно, що код, що розглядається, буде спочатку скомпільований з урахуванням дії механізму ARC в еквівалентний код, наведений у прикладі 12.1.
Приклад 12.1. Можливий сценарій консервативного керування пам'яттю за допомогою механізму ARC
Далі набуває чинності оптимізатор ARC, зменшуючи обсяг виконуваної роботи. Наприклад, він може виявити, що змінні myArray і myOtherArray перетворюються на покажчики на той самий об'єкт, і тому він може видалити деякі проміжні команди збереження та звільнення з пам'яті. Крім того, оптимізатор ARC може виявити, що надсилати команду release порожньому значенню nil не потрібно. Але команди збереження та звільнення з пам'яті настільки ефективні, коли діє механізм ARC, що навряд чи матиме велике значення, якщо оптимізатор не видалить будь-які проміжні команди збереження та звільнення з пам'яті.
Набагато більше значення має врівноваження ручного керування пам'яттю, ніж узгоджене виконання команд retain та release. Зокрема, як згадувалося раніше, команди alloc і сміття породжують об'єкти, підрахунок посилань яких вже збільшений, і тому вони також повинні бути врівноважені командою release. Щоб підпорядковуватися цій частині правил управління пам'яттю серед Cocoa, механізм ARC вдається до припущень щодо іменування методів.
Зокрема, коли в прикладному коді виходить об'єкт як значення, що повертається в результаті виклику методу, ARC шукає початкове слово (або кілька слів) в імені методу, що має змішане написання. (Терміном змішаненаписання описується складове слово, окремі слова якого починаються з великої літери, наприклад: ЗмішанеНаписання.) Якщо початковим словом в імені методу виявляється alloc, init, new, сміття або mutableCopy, то в механізмі ARC передбачається, що об'єкт повертається методом разом зі збільшеним підрахунком збережених посилань, яке має бути врівноважене відповідною командою release.
Так, якби в наведеному вище прикладі в результаті виклику [NSArray new] замість виклику [NSArray array] був отриманий масив, то механізму ARC стало б відомо, що буде потрібно додаткове звільнення з пам'яті, щоб врівноважити збільшений підрахунок посилань на об'єкт, що повертається з метод, ім'я якого починається на new.
У зв'язку з цим на вас покладається відповідальність не іменувати свої методи таким чином, щоб викликати сигнал тривоги у механізму ARC. Тому найпростіше не починати імена будь-яких методів з alloc, init (якщо тільки не йдеться про написання ініціалізатора), new, сміття або mutableCopy. Вживання цих слів в іменах методів навряд чи завдасть багато шкоди, але все ж таки краще не ризикувати, але підкорити, наскільки це можливо, механізм ARC угодам про іменування. (З цього скрутного становища є й інші шляхи виходу, якщо невірно іменовані методи не можна ніяк змінити, але вони не розглядаються.)