2011-10-25 10 views
42

В чем преимущества и недостатки использования стиля управления автоматической записью (ARC) в проекте iOS?Каковы преимущества и недостатки использования ARC?

Можете ли вы не использовать ARC при разработке с iOS 5.0 SDK?

Вы рекомендуете ARC или ручной подсчет ссылок (MRC) для нового проекта?

Будет ли приложение, использующее ARC, работать в более старых версиях ОС, чем iOS 5.0?

+2

У вас есть несколько вопросов, два из которых рассматриваются в вопросах [Как работает новый механизм автоматического учета ссылок?] (Http://stackoverflow.com/questions/6385212/how-does-the-new- автоматический-отсчет-счет-механизм-работа) и [Xcode 4.2 с ARC: будет ли мой код работать даже на устройствах iOS с прошивкой старше 5.0?] (http://stackoverflow.com/questions/7768861/xcode-4-2 -with-arc-will-my-code-run-even-on-ios-devices-with-firmware-old-tha) –

ответ

60

В чем преимущества и недостатки использования нового стиля управления автоматической подсчетом ссылок (ARC) в проекте iOS?

Выполнение программы ARC почти идентично хорошо написанному MRC. То есть различия в поведении часто не поддаются определению, поскольку как порядок операций, так и производительность очень близки.

Если вы уже знаете, как реализовать приложения OS X или iOS с ручным подсчетом ссылок (MRC), ARC на самом деле не добавляет функциональности - это просто позволяет вам удалить операции подсчета ссылок из ваших источников.

Если вы не хотите изучать MRC, вы можете сначала попробовать ARC. Многие люди борются с или пытаются игнорировать распространенные практики MRC (пример: я представил несколько разработчиков objc для статического анализатора). Если вы хотите избежать этих проблем, ARC позволит вам отложить ваше понимание; вы не можете писать нетривиальные программы objc без понимания подсчета ссылок и сроков жизни и отношений, будь то MRC, ARC или GC. ARC и GC просто удаляют реализацию из ваших источников и делают правильную вещь в большинстве случаев. С ARC и GC вам все равно нужно будет дать некоторые рекомендации.

Я не оценил это, но, возможно, стоит упомянуть, что компиляция Источники ARC потребуют больше времени и ресурсов.

Если программа, которую вы разрабатываете, имеет довольно свободное использование подсчета ссылок (например, типичное количество авторелеаз), переход на ARC может действительно улучшить время выполнения вашей программы и использовать максимальную память.

Можете ли вы не использовать ARC при разработке с iOS 5.0 SDK?

Да, используя CLANG_ENABLE_OBJC_ARC. ARC совместим с двоичными файлами, и все, что действительно происходит, заключается в том, что компилятор делает все возможное, чтобы автоматически вводить соответствующие операции подсчета ссылок для вас на основе деклараций, видимых для текущего перевода (see my answer here as to why translation visibility is important). Поэтому вы можете также включить и отключить его для некоторых источников в проекте и включить его для других.

Смешанный режим (некоторые источники MRC и некоторые источники ARC), однако, довольно сложный и тонко, особенно для реализаций, которые могут быть дублированы компилятором (например, тело встроенной функции может быть неправильным). Такие проблемы с смешанным режимом будут очень трудно изолировать. Программы и источники ObjC++ будут , в частности сложными в этом отношении. Кроме того, поведение может отличаться в зависимости от настроек оптимизации (как один пример); программа, которая отлично работает в сборке отладки, может ввести утечку или зомби в выпуске.

Вы рекомендуете ARC или ручной подсчет ссылок (MRC) для нового проекта?

Лично я буду придерживаться MRC в течение некоторого времени. Даже если ARC был протестирован в реальном мире, скорее всего, останется ряд проблем, которые появятся в сложных сценариях, которые вы хотите избежать, чтобы быть первыми, кто знал и отлаживал. Коллекция мусора OS X - пример того, почему вы можете подождать. В качестве одного из примеров коммутатор может измениться при уничтожении объектов - ваши объекты могут быть уничтожены раньше и никогда не будут помещены в пулы автозапуска. Он также может изменить порядок, в котором выпущены ивары, которые могут иметь некоторые побочные эффекты.

У меня также есть большая база кода, в которой я не хочу терять неделю тестирование этой функции в настоящее время. Наконец, для меня важна обратная совместимость.

Будет ли приложение, использующее ARC, работать на более старых версиях ОС, чем iOS 5.0?

Если вы разрабатываете MRC, он будет обратно совместим. Если вы работаете с ARC, это не обязательно будет совместимо. Фактически, он может даже не компилироваться без небольшой дополнительной работы. Требования к среде исполнения доступны в некоторых более ранних версиях. See also this question. Если вам нужна обратная совместимость, ARC не будет вариантом для некоторых версий ОС.

Наконец, если бы вы ограничили выбор GC или ARC, я бы рекомендовал ARC.

+5

Действительно хороший комментарий. Мы обсуждали вопрос о переносе нашего крупного проекта с MRC на ARC, но мы считаем, что лучше использовать MRC для крупных проектов или сложных объектных моделей, потому что мы контролируем его. В большинстве случаев мы даже не вызываем сохранение/освобождение вручную. Мы сохраняем свойства для всего, и мы autorelease во время выделения. Но время от времени мы находим ситуацию, когда нам нужен прямой контроль над памятью. – Sulthan

+0

Я потратил не одну неделю, а два дня на перенос своей 2D-библиотеки на основе OpenGL ES, и я могу сказать вам ... Если вы постоянно обращаетесь к ivars (чтобы избежать накладных расходов и потому, что вы знаете, что делаете), вы есть много делегатов, для которых вы забыли добавить __unsafe_unretained и т. д. Вы можете закончить множество циклов сохранения, реализуя -dealloc, чтобы добавить NSLog, чтобы узнать, освобожден ли объект, много головных болей в моем случае , Добавьте к этому проблемы совместимости с Xcode, ошибки в помощнике, неудачные миграции ... –

+0

В настоящее время я ** ** принимаю ARC, но только для небольших проектов на основе UIKit, где я могу позволить себе использовать self.this self , что все время и все вписывается в предполагаемые варианты использования Apple. –

1

вы отключите/выключите его с помощью CLANG_ENABLE_OBJC_ARC = NO Преимущество в том, что вам нужно писать меньше кода и управлять памятью проще. Недостатком является то, что вам нужно поцарапать все, что вы узнали об управлении памятью :) Я предпочитаю отключить его.

+0

Также может быть небольшое снижение производительности, если вы используете ARC –

+0

Фактически ARC обычно быстрее во время выполнения , главным образом потому, что оптимизатор выпускает объекты, как только это возможно, и меньше полагается на пулы автоопределения. – pchap10k

+2

Это сложнее, чем это. ARC работает быстрее * и * медленнее, в зависимости от ситуации. Типичные результаты: большее количество сохранений и выпусков (медленнее), меньше автореализаций (быстрее, меньше памяти). Единственный способ узнать, будет ли он быстрее или медленнее для вашего конкретного кода измерять. –

0

Вы можете включить ARC через «Edit-> Refactor-> Convert to Objective C Arc», это полностью реорганизует ваш код (избавится от всех вызовов управления памятью и т. Д.). Нет обратной операции, поэтому убедитесь, что у вас есть вещи под контролем источника, если у вас есть мысли. This post показывает, как отключить его для определенных файлов. Я не думаю, что есть слишком много аргументов в пользу того, чтобы не обращать на него внимания, кроме того, что ему больно видеть, что все это усилие, поставленное в правильное управление памятью, идет вниз, и что нам придется прекратить прыгать к потолку каждый раз, когда мы видим init, new, копируем без соответствующего релиза/autorelease (и это немного привыкает). Возможно, можно утверждать, что в некоторых случаях ручное управление памятью приводит к действительно заметным улучшениям производительности/памяти, поэтому мне также будет интересно.

0

Я использую Lion и xcode 4.3. У меня была та же проблема.

Чтобы исправить это, я включил «Build Settings-> Objective-C Automatic Reference Co» в «No».

Чтобы увидеть, что оно установлено в «Да», мне также необходимо включить параметры «Все» и «Уровни» на панели инструментов, расположенной чуть ниже панели инструментов «Настройки сборки».

Как только эти параметры были включены, я мог видеть, что у моего проекта была опция, установленная на «Да». Мне потребовалось некоторое время, чтобы понять, что значение по умолчанию было «Нет», что отображается, пока я не включил опцию «Уровни».