Я еще не использовал ARC, поскольку большая часть кода в проекте, над которым я сейчас работаю, была написана до iOS 5.0.
Мне просто интересно, перевешивает ли удобство отказа от сохранения / выпуска вручную (и, вероятно, более надежного кода, который в результате появляется?) Любую «стоимость» использования ARC? Каков ваш опыт использования ARC и вы бы порекомендовали его?
Так:
- Какую пользу ARC может принести проекту?
- Есть ли у ARC такая же стоимость, как сборка мусора в Java?
- Вы использовали ARC, и если да, то как вы его нашли?
iphone
objective-c
ipad
ios5
automatic-ref-counting
Саймон Витингтон
источник
источник
Ответы:
Обратной стороны нет. Используй это. Сделай это сегодня. Это быстрее, чем ваш старый код. Это безопаснее, чем ваш старый код. Это проще, чем ваш старый код. Это не сборщик мусора. У него нет накладных расходов времени выполнения GC. Компилятор вставляет удержания и освобождает все места, которые у вас должны быть. Но он умнее вас и может оптимизировать те, которые на самом деле не нужны (точно так же, как он может разворачивать циклы, удалять временные переменные, встроенные функции и т. Д.)
Хорошо, теперь я расскажу о небольших минусах:
Если вы давно являетесь разработчиком ObjC, вы будете дергаться около недели, когда увидите код ARC. Вы очень быстро с этим справитесь.
При переходе к коду Core Foundation возникают некоторые (очень) небольшие сложности. Есть немного больше сложностей в работе со всем, что рассматривает
id
какvoid*
.id
Для правильного выполнения таких вещей, как C-массивы, нужно немного подумать. Причудливое обращение с ObjCva_args
также может вызвать проблемы. Большинство задач, связанных с математикой для указателя ObjC, сложнее. В любом случае у вас не должно быть много этого.Вы не можете поместить
id
вstruct
. Это довольно редко, но иногда используется для упаковки данных.Если вы не следовали правильному именованию KVC, и вы смешиваете код ARC и не-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 и никогда не оглядывайтесь назад.
РЕДАКТИРОВАТЬ
Я видел пару комментариев вроде «использование ARC не заменяет знание правил управления памятью Какао». В основном это правда, но важно понимать, почему и почему нет. Во-первых, если весь ваш код использует ARC, и вы нарушаете Три волшебных словаповсюду, у вас все равно не будет проблем. Это шокирует, но вот и все. ARC может сохранить некоторые вещи, которые вы не хотели сохранять, но также освободит их, так что это не имеет значения. Если бы я преподавал сегодня новый класс в Какао, я бы, вероятно, потратил не более пяти минут на фактические правила управления памятью и, вероятно, упомянул бы только правила именования управления памятью при обсуждении именования KVC. Я считаю, что с ARC вы действительно можете стать приличным начинающим программистом, вообще не изучая правил управления памятью.
Но вы не смогли бы стать достойным программистом среднего уровня. Вам необходимо знать правила, чтобы правильно соединиться с Core Foundation, и каждый промежуточный программист должен иметь дело с CF в какой-то момент. И вам нужно знать правила для кода смешанного ARC / MRC. И вам нужно знать правила, когда вы начинаете возиться с
void*
указателями наid
(которые вам по-прежнему нужны для правильного выполнения KVO). А блоки ... ну, управление блочной памятью - это просто странно.Итак, я хочу сказать, что базовое управление памятью по-прежнему важно, но там, где я тратил много времени на формулирование и повторение правил для начинающих программистов, с ARC это становится более сложной темой. Я бы предпочел, чтобы новые разработчики думали в терминах графов объектов, а не забивали им головы базовыми вызовами
objc_retain()
.источник
Будет получено больше технических ответов, чем у меня, но вот что:
источник
Преимущество заключается в значительной степени защиты от распространенных ошибок управления памятью. Утечки, вызванные невозможностью освободить объект и сбои из-за невозможности удержания или преждевременного высвобождения объекта, должны быть значительно уменьшены. Вам по-прежнему необходимо понимать модель памяти с подсчетом ссылок, чтобы вы могли классифицировать свои ссылки как сильные или слабые, избегать циклов сохранения и т. Д.
В iOS нет сборки мусора. ARC похож на GC в том, что вам не нужно вручную сохранять или освобождать объекты. В отличие от GC, здесь нет сборщика мусора. Модель сохранения / освобождения по-прежнему применяется, просто компилятор вставляет соответствующие вызовы управления памятью в ваш код во время компиляции.
Это немного сбивает с толку, если вы привыкли к подсчету ссылок, но это просто вопрос привыкания к нему и обучения вере в то, что компилятор действительно поступит правильно. Это похоже на продолжение изменения свойств, которое появилось в Objective-C 2.0, что стало еще одним большим шагом на пути к упрощению управления памятью. Без вызовов ручного управления памятью ваш код становится немного короче и легче читается.
Единственная проблема с ARC заключается в том, что он не поддерживается в более старых версиях iOS, поэтому вам необходимо принять это во внимание, прежде чем вы решите принять его.
источник
Я думаю, что ARC - отличная идея. По сравнению с GC, вы можете съесть свой торт и съесть его. Я склонен полагать, что MRC устанавливает бесценную «дисциплину» в отношении управления памятью, от которой выиграет каждый. Но я также согласен с тем, что настоящая проблема, о которой нужно знать, - это владение объектами и графы объектов (как многие указывали), а не низкоуровневые подсчеты ссылок как таковые.
В заключение: ARC - это НЕ бесплатный пропуск, чтобы не думать о памяти; это инструмент, который помогает людям избегать повторяющихся задач, которые вызывают стресс и подвержены ошибкам, поэтому лучше делегировать их машине (в данном случае компилятору).
Тем не менее, я лично своего рода ремесленник и еще не совершил переход. Я только начал использовать Git ...
ОБНОВЛЕНИЕ: Итак, я перенес всю свою игру, включая библиотеку gl, и пока никаких проблем (за исключением помощника по миграции в Xcode 4.2). Если вы начинаете новый проект, дерзайте.
источник
Я использовал его в паре (правда, небольших) проектов, и у меня есть только хорошие впечатления как с точки зрения производительности, так и надежности.
Одно небольшое предостережение: вам нужно изучить, что делать и не делать слабых ссылок, чтобы не вызывать циклы ссылок, если вы кодируете свой пользовательский интерфейс самостоятельно, дизайнер, как правило, хорошо с этим справляется. автоматически, если вы настроили свой графический интерфейс с его помощью.
источник
Единственный недостаток, с которым я столкнулся, - это использование библиотеки с множеством функций и данных CoreFoundation. В MRC вам не нужно было беспокоиться об использовании
CFStringRef
вместоNSString*
. В ARC вы должны указать, как они взаимодействуют (базовый мост? Освободить объект CoreFoundation и переместить его в ARC? Сделать объект Какао как сохраненный объект +1 CoreFoundation?) Кроме того, в OS X он доступен только в 64- битовый код (хотя у меня есть заголовок, который позволяет обойти это…).источник