Подтвердить что ты не робот

Какова стоимость использования авторекламы в Cocoa?

Большая часть документации на яблоки, кажется, не позволяет использовать объекты с автореализацией, особенно при создании представлений gui, но я хочу знать, какова стоимость использования автореализованных объектов?

UIScrollView *timeline = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 20, 320, 34)];
[self addSubview:timeline];
[timeline release];

В конечном итоге следует использовать стратегию, в которой все автореализован и использование сохранения/выпуска должно быть исключением из правила для конкретных случаев? Или я должен вообще использовать сохранение/освобождение с авторекламой, являющейся исключением для возвращаемых объектов из удобных методов, таких как [NSString stringWithEtc...]?

4b9b3361

Ответ 1

Есть две стоимости:

  • (Предполагая, что у вас есть возможность избежать автореализованных объектов.) Вы фактически излишне увеличиваете срок службы своих объектов. Это может означать, что ваш объем памяти растет - излишне. На ограниченной платформе это может означать, что ваше приложение прекращается, если оно превышает лимит. Даже если вы не превысите лимит, это может привести к тому, что ваша система начнет свопинг, что очень неэффективно.

  • Дополнительные накладные расходы на поиск текущего пула авторесурсов, добавление к нему объекта автореализации и последующее освобождение объекта в конце (вызов дополнительного метода). Это может не быть большими накладными расходами, но это может сложить.

Лучшая практика на любой платформе - попытаться избежать авторекламы, если сможете.

Чтобы ответить на вопросы:

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

Совсем наоборот.

Или вообще я должен использовать сохранение/освобождение, когда autorelease является исключением для возвращаемых объектов из удобных методов, таких как [NSString stringWithEtc...]?

Вы всегда должны использовать сохранение/освобождение, если можете - в случае NSString, как правило, нет необходимости использовать методы stringWithEtc, поскольку существуют эквиваленты initWithEtc.

См. также этот вопрос.

Ответ 2

Я должен не соглашаться с Джимом Пулсом - я думаю, что не, использующий Autorelease, делает отладку более сложной, потому что вы, скорее всего, обнаружите, что случайно протекаете память. Конечно, статический анализатор Clang может забрать некоторые из этих экземпляров, но для меня небольшие накладные расходы, обычно использующие autorelease, намного омрачены тем, что мой код менее подвержен ошибкам.

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

Ответ 3

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

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

Ответ 4

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

Несмотря на потерю эффективности, в большинстве случаев это не имеет значения. Большая проблема заключается в том, что объекты с более длинными объектами и последующее восстановление памяти могут привести к более фрагментированному адресному пространству. Если это проблема, обычно довольно просто входить и переключиться на ручное сохранение/освобождение несколькими горячими методами и улучшить его.

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

Ответ 5

Одним из преимуществ использования пулов автоопределения является то, что они являются безопасными для исключения без использования @try/@finally. Грэг Паркер ( "Mr. Objective-C" ) имеет отличный пост, объясняющий подробности этого.

Я часто использую autorelease как свой меньший код и делает его более читаемым, IMO. Недостаток, как указывали другие, заключается в том, что вы увеличиваете время жизни объектов, тем самым временно используя больше памяти. На практике мне еще предстоит найти чрезмерное использование autorelease для значимой проблемы в любом приложении Mac, которое я написал. Если использование большой памяти кажется проблемой (это не вызвано подлинной утечкой), я просто добавляю больше пулов автоопределения (после профилирования, чтобы показать мне, где они мне нужны). Но, в общем, это довольно редко. Как показывает Майк Эш (Graham Lee), автореферационные бассейны имеют очень мало накладных расходов и быстры. Там почти нулевая стоимость добавляет больше пулов автозапуска.

Конечно, это все для приложений Mac. В приложениях iPhone, где память более жесткая, вы можете быть консервативны при использовании авторекламы. Но, как всегда, сначала напишите читаемый код, а затем оптимизируйте его позже, измеряя, где находятся детали с медленной/интенсивной памятью.

Ответ 6

Расходы:

  • Время поиска текущего пула авторесурсов потока и добавления к нему объекта.
  • Память, занятая объектом, пока она не будет выпущена в какой-то более поздней точке.

Если вы хотите быть очень консервативным при использовании вашей памяти, вам следует избегать автообновления. Однако это полезный метод, который может сделать код более читаемым. Навязчиво используя сохранение/освобождение подпадает под "предварительную оптимизацию".

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

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

Если вы не можете избежать автореализаций внутри цикла (это делается с помощью кода, который вы не писали и не можете изменить), вы также можете самостоятельно управлять NSAutoreleasePool внутри цикла.

Итак, помните о том, чтобы использовать авторекламу внутри циклов (или методов, которые могут быть вызваны из циклов), но не избегайте этого, когда это может сделать код более читаемым.

Ответ 7

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

Ответ 9

Я заметил, что образец кода, который вы предоставили, предназначен для iPhone. Apple рекомендует избегать автореализованных объектов для приложений iPhone. Я не могу найти конкретные аргументы, но они забивали этот момент в WWDC.

Ответ 10

Однобочечное примечание, которое следует иметь в виду, - это если вы создаете новый поток, вы должны настроить новый пул автозапуска в этом потоке, прежде чем делать что-либо еще. Даже если вы не используете объекты автозапуска, есть вероятность, что в API Cocoa есть что-то.

Ответ 11

Старый поток, но чиппинг в интересах новых читателей.

Я использую autorelease vs keep/release в зависимости от риска ошибок автообновления, специфичных для объекта, и размера объекта. Если я просто добавлю несколько маленьких UIImageViews или пару UILabels к моему представлению, autorelease сохраняет код читаемым и управляемым. И когда представление удалено и отменено, эти подпункты должны быть выпущены достаточно скоро.

Если, с другой стороны, мы говорим об UIWebView (высокий риск ошибок автозапуска) или, конечно же, некоторые данные, которые должны быть постоянными до "смерти" объекта, сохранить/освободить - это путь.

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

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