До ARC чи ні до ARC? Які плюси і мінуси? [зачинено]


113

Я ще не використовую ARC, оскільки більшість кодів у проекті, над яким я працюю на даний момент, було написано до iOS 5.0.

Мені було просто цікаво, чи переважає зручність не зберігати / звільняти вручну (і, мабуть, більш надійний код, що виникає в результаті?) Будь-яку «вартість» використання ARC? Який у вас досвід ARC, і чи рекомендуєте ви це?

Так:

  • Скільки користі може принести ARC проекту?
  • Чи ARC має таку вартість, як збирання сміття на Яві?
  • Чи використовували ви ARC і якщо так, то як ви його знайшли досі?

Збір сміття на ipad / ios відсутній. Ви говорите про OS X?
dasblinkenlight

1
Вибачте, я використовую терміни Java поза місцем. Я маю на увазі, що за допомогою ARC об’єкти можуть зберігатися в пам'яті довше, ніж потрібно, а потім вивільнятися як група в пулі автоматичних випусків через деякий час. Саме завдяки цьому вони зберігаються та вивільняються з іншими об’єктами пізніше, подібно до збирання сміття Java.
Саймон Уінґінгтон

3
@TenementFunster, для того ж коду (за вирахуванням викликів до звільнення) ARC буде тримати об'єкт довше, ніж не-ARC-код. Насправді, він часто звільнить його раніше, ніж ви мали б. Існує невелика кількість речей, які дещо повільніші, але вони прискорюють загальні зразки настільки сильно, що це глушить вплив продуктивності. Для багатьох поширених шаблонів (зберігаючи об'єкт, який повернувся, наприклад, з автоматичним випуском), ви буквально не можете записати його вручну так швидко, як ARC зробить це автоматично.
Роб Нап'є

1
Що стосується вивезення сміття, дивіться мою відповідь на подібний подібний запитання: Яка різниця між автоматичним підрахунком посилань Objective-C і вивезенням сміття?
Бред Ларсон

Відповіді:


147

Немає недоліків. Використай це. Зробіть це сьогодні. Це швидше, ніж ваш старий код. Це безпечніше, ніж ваш старий код. Це простіше, ніж ваш старий код. Це не збирання сміття. У нього немає накладних витрат GC. Компілятор вставляє і зберігає у всіх місцях, де ви повинні мати місце. Але він розумніший за вас і може оптимізувати ті, які насправді не потрібні (так само, як він може розкручувати цикли, виключати тимчасові змінні, вбудовані функції тощо).

Гаразд, зараз я розповім вам про невеликі недоліки:

  • Якщо ви давно розробник ObjC, ви будете смикатися приблизно тиждень, коли побачите код ARC. Ви дуже швидко переберете це.

  • Існує кілька (дуже) невеликих ускладнень при встановленні коду Core Foundation. Існує дещо більше ускладнень у роботі з будь-чим, що трактується idяк "a" void*. Такі речі, як C-масиви, idможуть задуматися над тим, щоб зробити правильно. Неохайне поводження з ObjC va_argsтакож може спричинити проблеми. Більшість речей, що стосуються математики на покажчику ObjC, складніше. У вас не повинно бути багато цього в будь-якому випадку.

  • Ви не можете поставити idа struct. Це досить рідко, але іноді використовується для пакування даних.

  • Якщо ви не дотримувались правильного іменування KVC та змішуєте код ARC та non-ARC, у вас виникнуть проблеми з пам'яттю. ARC використовує KVC іменування для прийняття рішень щодо управління пам'яттю. Якщо це все ARC-код, то це не має значення, оскільки це зробить це те саме "неправильно" з обох сторін. Але якщо це змішаний ARC / non-ARC, то тут є невідповідність.

  • ARC буде просочувати пам'ять під час викидів ObjC. Виняток ObjC має бути дуже близьким за часом до припинення вашої програми. Якщо ви збираєте значну кількість винятків ObjC, ви використовуєте їх неправильно. Це можна виправити за допомогою -fobjc-arc-exceptions, але воно несе пені, про які йдеться нижче:

  • ARC не просочується пам'яті під час викидів ObjC або C ++ у винятковому коді ObjC ++, але це коштує як часу, так і простору. Це ще одна з довгого списку причин, щоб мінімізувати використання ObjC ++.

  • ARC взагалі не працюватиме на iPhoneOS 3 чи Mac OS X 10.5 або новіших версій. (Це не дозволяє мені використовувати ARC у багатьох проектах.)

  • __weakпокажчики не працюють належним чином на iOS 4 або Mac OS X 10.6, що шкода, але обходити досить просто. __weakпокажчики чудові, але вони не є першою точкою продажу ARC.

Для 95% + коду там ARC є геніальним, і немає жодних причин уникати цього (за умови, що ви можете керувати обмеженнями версії ОС). Що стосується коду, що не стосується ARC, ви можете передавати -fno-objc-arcйого по кожному файлу. На жаль, Xcode робить це набагато складніше, ніж це слід зробити на практиці. Ви, мабуть, повинні перемістити код, який не є ARC, в окремий xcodeproj, щоб спростити це.

На закінчення переходьте на ARC, як тільки зможете, і ніколи не озирайтеся назад.


EDIT

Я бачив пару коментарів: "використання ARC не замінює знання правил управління пам'яттю какао". Це здебільшого правда, але важливо зрозуміти, чому і чому ні. По-перше, якщо весь ваш код використовує ARC, а ви порушуєте Три магічні словавсюди у вас все одно не буде проблем. Шокуюче сказати, але там ви йдете. ARC може зберегти деякі речі, які ви не мали на увазі зберегти, але вони також випустять їх, так що це ніколи не матиме значення. Якби я сьогодні викладав новий клас у Какао, я, мабуть, витратив не більше п’яти хвилин на фактичні правила управління пам’яттю, і, напевно, згадував би лише правила іменування управління пам’яттю під час обговорення імен KVC. З ARC, я вважаю, що ви насправді можете стати гідним початківцем програмістом, навіть не вивчаючи правил управління пам'яттю.

Але ти не міг стати гідним проміжним програмістом. Вам потрібно знати правила, щоб правильно з'єднатись із Core Foundation, і кожен програміст-проміжник повинен в якийсь момент мати справу з МВ. І вам потрібно знати правила для змішаного коду ARC / MRC. І вам потрібно знати правила, коли ви починаєте возитися з void*вказівниками на id(які вам і надалі потрібно виконувати KVO правильно). І блоки ... ну, керування пам'яттю блоків просто дивно.

Отже, моя думка полягає в тому, що основне управління пам’яттю все ще важливе, але там, де я витрачав значний час на констатацію та перезапуск правил для нових програмістів, ARC це стає більш вдосконаленою темою. Я вважаю за краще, щоб нові розробники думали з точки зору об'єктних графіків, а не наповнювали їх головами основними закликами до objc_retain().


3
Одне, на що слід бути дуже обережним (як і в не-ARC, але тим більше, що в ARC, оскільки це зараз так непомітно), - це зберігати цикли. Моя порада тут: 1) якщо ви виявите, що ви зберігаєте блок objc як змінну екземпляра, уважно погляньте на нього, щоб побачити, чи може він захопити об'єкт, який є ivar, навіть опосередковано. 2) Насправді спроектуйте свій об’єктний графік, а не просто дозвольте це робити. Ви повинні знати, що належить, що, якщо ви хочете написати хороший код. 3) Використовуйте посилання: friday.com/bbum/2010/10/17/…
Catfish_Man

1
@Catfish_Man Усі хороші моменти. Збереження циклів завжди було проблемою. Нова порада Apple - це точно так, як ви кажете в №2. Нам потрібно думати про об’єктні графіки, а не зберігати та випускати. №1 - це серйозна проблема з блоками, і одна з декількох причин я вважаю, що в блоках є змішане благо, до якого слід підходити обережно.
Роб Нап'єр

2
Є один серйозний мінус, про який не згадувалося: перехресна сумісність. Для нас сміливих і дурних душ, які стикаються з пустирями, відомими як кросплатформенне програмування, ARC просто не є варіантом, принаймні не до тих пір, поки GNU знову не розширить свої функції виконання та компіляції ObjC (вони кажуть, що на шляху є більше).
Кролик

2
Ви можете використовувати ARC, за винятком того, що вам потрібно підтримувати пристрої iOS 3.x. BTW, переконайтеся, що для переходу використовуйте Xcode (Правка> Рефактор> Перетворити в ARC Objective-C). Під час процесу Xcode зробив би велику перевірку, щоб переконатися, що ваш код буде працювати, і з'ясувати будь-які коди, що порушують ці інструкції щодо проектування.
Чжанчн

1
Відмінно .. відповідь точково. це 100-й у мене. Поздравляємо століття;)
Аджай Шарма

20

Краще, більше технічних відповідей, ніж мої, надійде:

  • ARC! = Вивезення сміття. Немає покарання за виконання часу, це робиться під час компіляції.
  • ARC також! = Просто автоматично випускає все, як ви пропонуєте у своєму коментарі. Прочитайте документи
  • Це приголомшливо , коли ви розумієте , як багато ручного управління посилального ви були робити
  • Використай це!
  • Один недолік - збереження старого недугового коду раптом стає дуже стомлюючим.

Так, тому я до цього часу не використовував її - я не впевнений, що міг би перенести нашу значну кількість попередньо існуючого коду для його перетворення ... Я обов'язково спробую це наступний проект. Дякую за Вашу відповідь :)
Саймон Уінґінгтон

Справа не в тому, що підтримувати старий код стає складніше, це те, що ваші сподівання змінилися. Тож справді не справедливо звинувачувати ARC у тому, щоб полегшити життя. Xcode дозволяє легко перетворити ваш старий код у ARC, коли ви готові, але ви, очевидно, не можете його використовувати, якщо вам все-таки потрібно підтримувати старіші версії iOS.
Калеб

1
@Caleb Я не звинувачував ARC, це лише єдиний недолік, який я бачив досі - його зіпсували мене гнилі в просторі одного проекту.
jrturton

Так; Я не перераховував це як проблему, але існує невелика проблема виходу з практики управління пам’яттю, коли вам доведеться перемикатися між базами коду. Деякі з моїх проектів працюють на 10.4, тому я все ще роблю багато роботи з Objective-C 1.0 (так що ні @synthesize, не кажучи вже про ARC). Але ти звикаєш до перемикання режимів досить добре.
Роб Нап'єр

@jrturton Я повинен був би дати зрозуміти, що я написав це на користь ОП та майбутнім читачам, які, можливо, не роблять того, що робить ARC. Я точно знаю, що ви маєте на увазі, просто не хотів, щоб хтось робив помилковий висновок про те, що змішування ARC та не-ARC-коду створює проблему.
Калеб

16

Скільки користі може принести ARC проекту?

Перевага полягає у значному ступені захисту від поширених помилок управління пам’яттю. Витоки, спричинені відмовою від випуску об'єкта та збоями внаслідок відмови об'єкта або передчасного його вивільнення, повинні бути значно зменшені. Вам все ще потрібно зрозуміти модель опорної лічильної пам'яті, щоб ви могли класифікувати свої посилання як сильні чи слабкі, уникати циклів утримання тощо.

Скільки насправді "коштує" вивезення сміття?

Збір сміття в iOS відсутній. ARC схожий на GC тим, що вам не потрібно вручну зберігати чи звільняти об'єкти. На відміну від GC в тому, що немає сміттєзбірника. Модель збереження / випуску все ще діє, просто компілятор вставляє відповідні виклики управління пам'яттю у ваш код для вас під час компіляції.

Чи використовували ви ARC і якщо так, то як ви його знайшли досі?

Трохи неприємно, якщо ви звикли посилатись на підрахунок, але це лише питання звикання до нього та навчитися вірити, що компілятор дійсно зробить правильно. Це здається продовженням змін у властивостях, які відбулися з Objective-C 2.0, що було ще одним великим кроком до спрощення управління пам’яттю. Без дзвінків з керування пам'яттю вручну ваш код стає трохи коротшим і простішим для читання.

Єдине питання ARC полягає в тому, що він не підтримується в старих версіях iOS, тому вам потрібно це врахувати, перш ніж вирішити його прийняти.


1
Є краща відповідь, про яку я говорив!
jrturton

1
Так, чудова відповідь. Тож насправді немає ARC, окрім необхідності навчитися вірити, що це працює? Здається, занадто добре, щоб бути правдою в такому випадку?
Simon Simon Withington

4

Я думаю, ARC - це чудова ідея. У порівнянні з GC, ви можете мати свій торт і їсти його теж. Я схильний вважати, що MRC нав'язує неоціненну «дисципліну» щодо управління пам’яттю, від якої кожен виграв би. Але я також погоджуюся з тим, що справжньою проблемою слід знати, як графіки власності на об'єкти та об'єкти (як багато вказували), а не низькі рівні посилання самі по собі.

На закінчення: ARC НЕ є безкоштовним пропуском, щоб бути бездумним щодо пам’яті; це інструмент, який допомагає людині уникати повторюваних завдань, які викликають стрес та схильні до помилок, тому краще делегуватись машині (компілятору в цьому випадку).

Це сказало, що я особисто є майстром і ще не здійснив перехід. Я щойно почав використовувати Git ...

ОНОВЛЕННЯ: Отже, я перемістив всю свою гру, включена бібліотека gl, і поки що немає проблем (за винятком помічника з міграції у Xcode 4.2). Якщо ви починаєте новий проект, продовжуйте його виконувати.


2

Я використовував це в декількох (правда, невеликих) проектах, і у мене є лише хороший досвід, як продуктивний, так і надійний.

Одна незначна нотка обережності полягає в тому, що вам потрібно навчитися робити: s і don’t: s слабких посилань, щоб не викликати циклів посилань, якщо ви кодуєте свій інтерфейс самостійно, дизайнер прагне добре виконати його. автоматично, якщо ви налаштували його GUI, використовуючи його.


2

Єдиний недолік, з яким я зіткнувся, - це якщо ви користуєтеся бібліотекою з великою кількістю функцій і даних CoreFoundation. У MRC вам не потрібно було турбуватися про використання CFStringRefзамість цього NSString*. В ARC ви повинні вказати, як взаємодіють два (базовий міст? Випустіть об’єкт CoreFoundation і перемістіть його в ARC? Створіть об'єкт Какао як об'єкт +1, який зберігається в CoreFoundation?) Також в OS X він доступний лише на 64- бітовий код (Хоча в мене є заголовок, який працює навколо цього…).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.