Дуга или не дуга? Каковы плюсы и минусы? [закрытый]


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

Мне просто интересно, есть ли удобство не сохранять / освобождать вручную (и, по-видимому, более надежный код, который приходит в результате?) перевешивают любые "затраты" на использование дуги? Каковы ваши впечатления от ARC, и вы бы порекомендовали его?

Так:

  • сколько пользы может принести ARC проекту?
  • тут ARC имеет стоимость, как сбор мусора в Java?
  • вы использовали ARC и если да, то как вы нашли его до сих пор?
6 111

6 ответов:

нет никаких недостатков. Использовать его. Сделать это сегодня. Это быстрее, чем ваш старый код. Это безопаснее, чем ваш старый код. Это проще, чем ваш старый код. Это не сбор мусора. Он не имеет накладных расходов времени выполнения GC. Компилятор вставляет сохраняет и освобождает во всех местах, которые вы должны иметь в любом случае. Но он умнее вас и может оптимизировать те, которые на самом деле не нужны (так же, как он может разворачивать циклы, устранять временные переменные, встроенные функции и т. д.)

хорошо, теперь я расскажу вам о маленьких минусах:

  • если вы являетесь давним разработчиком ObjC, вы будете дергаться около недели, когда увидите код ARC. Вы очень быстро справитесь с этим.

  • есть некоторые (очень) небольшие осложнения в соединении с основным кодом фундамента. Есть немного больше осложнений в работе с чем-либо, что лечит id Как void*. Вещи, как C-массивы id можно еще немного подумать делать правильно. Необычные обработки язык va_args также может вызвать проблемы. Большинство вещей, связанных с математикой на указателе ObjC, сложнее. В любом случае, у вас не должно быть много этого.

  • вы не можете поставить id на struct. Это довольно редко, но иногда используется для упаковки данных.

  • если вы не следовали правильному именованию KVC, и вы смешиваете код дуги и не дуги, у вас будут проблемы с памятью. ARC использует именование KVC для создания решения об управлении памятью. Если это все Arc-код, то это не имеет значения, потому что он будет делать это одинаково "неправильно" с обеих сторон. Но если это смешанная дуга/не дуга, то есть несоответствие.

  • дуга будет утечка памяти в форматы исключение бросает. Исключение 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 указатели великолепны, но они не являются точкой продажи № 1 ARC.

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

в заключение, переключитесь на дугу, как только сможете, и никогда не оглядывайтесь назад.


EDIT

Я видел несколько комментариев по строкам "использование ARC не заменяет знание правил управления памятью Cocoa."Это в основном правда, но важно понять, почему и почему нет. Во-первых, если весь ваш код использует ARC, и вы нарушаете Три Волшебных Слова везде, вы все еще не будете иметь никаких проблем. Стыдно сказать, но там вы идете. ARC может сохранить некоторые вещи, которые вы не хотели, чтобы он сохранил, но он также освободит их, поэтому это никогда не будет иметь значения. Если бы я сегодня преподавал новый класс в Cocoa, я бы, вероятно, потратил не более пяти минут на фактические правила управления памятью, и я бы, вероятно, только упомянул правила управления памятью при обсуждении именования KVC. С ARC, я верю, что вы могли бы на самом деле стать приличным начинающим программистом, не изучая правила управления памятью вообще.

но вы не могли стать приличным промежуточным программистом. Вам нужно знать правила, чтобы правильно построить мост с Core Foundation, и каждый промежуточный программист должен иметь дело с CF в какой-то момент. И вам нужно знать правила для кода mixed-ARC / MRC. И вы должны знать правила, когда вы начинаете возиться с void* указатели id (который вы продолжаете нужно выполнить кво правильно). И блоки... ну, управление блочной памятью просто странно.

Итак, я хочу сказать, что базовое управление памятью по-прежнему важно, но там, где я проводил значительное время, заявляя и переформулируя правила для новых программистов, с ARC это становится более продвинутой темой. Я бы предпочел, чтобы новые разработчики думали в терминах графов объектов, а не заполняли их головы базовыми вызовами objc_retain().

лучше, больше технических ответов, чем мои придут, но вот идет:

  • дуга != сборка мусора. Нет штрафа за время выполнения, это делается во время компиляции.
  • дуги тоже != просто автоматическое освобождение всего, как вы предлагаете в своем комментарии. Читайте docs
  • Это потрясающе, как только вы поймете, сколько ручного управления ссылками вы были делаешь
  • использовать его!
  • один недостаток-сохранение старого, код без дуги внезапно становится очень утомительным.

какую пользу может принести ARC проекту?

преимуществом является значительная степень защиты от распространенных ошибок управления памятью. Утечки, вызванные неспособностью освободить объект и сбоями из-за неспособности сохранить или преждевременно освободить объект, должны быть значительно уменьшены. Вам все еще нужно понять модель подсчитанной памяти ссылок, чтобы вы могли классифицировать свои ссылки как сильные или слабые, избегать циклов сохранения и т. д на.

сколько на самом деле стоит сбор мусора?

в iOS нет сборки мусора. ARC похожа на GC в том, что вам не нужно вручную сохранять или освобождать объекты. Это не похоже на GC в том, что нет сборщика мусора. Модель сохранения / выпуска по-прежнему применяется, просто компилятор вставляет соответствующие вызовы управления памятью в ваш код для вас во время компиляции.

вы использовали ARC и если Итак, как вы нашли его до сих пор?

это немного смущает, если вы привыкли к подсчету ссылок, но это просто вопрос привыкания к нему и обучения доверять тому, что компилятор действительно будет делать правильные вещи. Это похоже на продолжение изменения свойств, которые пришли с Objective-C 2.0, что стало еще одним большим шагом к упрощению управления памятью. Без ручного управления памятью вызовы, ваш код становится немного короче и проще читать.

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

Я думаю, что ARC-отличная идея. По сравнению с GC, вы можете иметь ваш торт и съесть его. Я склонен полагать, что MRC накладывает неоценимую "дисциплину" в отношении управления памятью, от которой выиграют все. Но я также согласен с тем, что реальная проблема, о которой нужно знать,-это владение объектами и графы объектов (как указывали многие), а не низкоуровневые ссылки как таковые.

В заключение: ARC-это не свободный проход, чтобы не думать о памяти; это инструмент, чтобы помочь людям избегайте повторяющихся задач, которые вызывают стресс и склонны к ошибкам, поэтому лучше делегировать их машине (в данном случае компилятору).

тем не менее, я лично своего рода ремесленник и еще не сделал переход. Я только начал использовать git...

обновление: поэтому я перенес всю свою игру, включая библиотеку gl, и до сих пор никаких проблем (кроме помощника по миграции в Xcode 4.2). Если вы начинаете новый проект, пойти на это.

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

одно небольшое замечание предостережения заключается в том, что вам нужно изучить do:s и don'T:s слабых ссылок, чтобы не вызывать каких-либо ссылочных циклов, если вы кодируете свой пользовательский интерфейс самостоятельно, дизайнер, как правило, делает хорошую работу автоматически, если вы настраиваете свой графический интерфейс с его помощью.

единственный недостаток, с которым я столкнулся, - это использование библиотеки с большим количеством функций и данных CoreFoundation. В MRC вам не нужно было беспокоиться об использовании CFStringRef вместо NSString*. В ARC вы должны указать, как они взаимодействуют (базовый мост? отпустите объект CoreFoundation и переместите его в ARC? Сделать объект Cocoa как + 1 CoreFoundation сохраненный объект?) Кроме того, в OS X он доступен только в 64-разрядном коде (хотя у меня есть заголовок, который работает вокруг этого...).