ARC - це просто відтворити старий режим збереження / випуску (MRC), при цьому компілятор з'ясовує, коли зателефонувати зберегти / випустити. Це, як правило, має більш високу продуктивність, менший пік використання пам'яті та більш передбачувану продуктивність, ніж система GC.
З іншого боку, деякі типи структури даних неможливо з ARC (або MRC), тоді як GC може обробляти їх.
Наприклад, якщо у вас є клас з назвою node, а у node є NSArray дітей і одна посилання на його батьків, що "просто працює" з GC. З ARC (і з підрахунком посилань вручну) у вас є проблеми. Будь-який даний вузол буде посилатися від його дітей, а також від його батьків.
Подібно до:
A -> [B1, B2, B3]
B1 -> A, B2 -> A, B3 -> A
Усе добре, коли ви використовуєте A (скажімо, через локальну змінну).
Коли ви закінчите з ним (і B1 / B2 / B3), система GC врешті вирішить переглянути все, що може знайти, починаючи з регістрів стека та процесора. Він ніколи не знайде A, B1, B2, B3, тому він доопрацює їх і переробить пам'ять в інші об’єкти.
Якщо ви використовуєте ARC або MRC, і закінчите з A, у нього буде знижка 3 (B1, B2 і B3 всі посилаються на нього), і B1 / B2 / B3 матиме посилання на 1 (A NSArray A містить одне посилання на кожен). Таким чином, всі ці об'єкти залишаються живими, хоча їх ніхто ніколи не може використовувати.
Загальне рішення - вирішити, що одна з цих посилань повинна бути слабкою (не сприяти підрахунку). Це буде працювати для деяких моделей використання, наприклад, якщо ви посилаєтесь на B1 / B2 / B3 лише через A. Однак у інших шаблонах це не вдається. Наприклад, якщо ви іноді будете триматися на B1, і очікуєте піднятися назад вгору через батьківський вказівник і знайдете А. Зі слабким посиланням, якщо ви тримаєтесь лише за B1, A може (і зазвичай буде) випаровуватися, і приймати B2, і B3 з цим.
Іноді це не проблема, але деякі дуже корисні та природні способи роботи зі складними структурами даних дуже важко використовувати з ARC / MRC.
Таким чином, ARC націлює однакові проблеми на цілі GC. Однак ARC працює на більш обмеженому наборі моделей використання, ніж GC, тож якщо ви взяли мову GC (наприклад, Java) і прищепили щось на зразок ARC на неї, деякі програми більше не працюватимуть (або, принаймні, генерують тонни занедбаної пам'яті , і може спричинити серйозні проблеми із заміною, або не вистачить пам’яті чи місця для обміну).
Ви також можете сказати, що ARC надає більшого пріоритету продуктивності (або, можливо, передбачуваності), тоді як GC надає більшого пріоритету тому, щоб бути загальним рішенням. В результаті GC має менші прогнозовані потреби в процесорі / пам'яті та більш низьку продуктивність (як правило), ніж ARC, але може працювати з будь-якою схемою використання. ARC буде працювати набагато краще для багатьох багатьох звичних моделей використання, але для кількох (дійсних!) Моделей використання він перепаде і загине.