Избегать автоматически выпущенных объектов, хорошей практики или излишеств? - PullRequest
5 голосов
/ 16 февраля 2011

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

// User Managed Memory
NSSet *buttonSizes = [[NSSet alloc] initWithObjects:@"Go", @"Going", @"Gone", nil];
[barItemLeft setPossibleTitles:buttonSizes];
[barItemRight setPossibleTitles:buttonSizes];
[buttonSizes release];

.

// Autoreleased Memory
NSSet *buttonSizes = [NSSet setWithObjects:@"Go", @"Going", @"Gone", nil];
[barItemLeft setPossibleTitles:buttonSizes];
[barItemRight setPossibleTitles:buttonSizes];

Ответы [ 6 ]

8 голосов
/ 16 февраля 2011

Тотальный перебор.Если вы внимательно прочитали соответствующую документацию, это не говорит о том, что вам следует избегать автоматического освобождения объектов.Это говорит о том, что вам следует избегать использования пулов автоматического выпуска, когда вы находитесь в тесных, богатых объектами циклах.В этих случаях вы должны явно управлять своей памятью (с помощью retain и release), чтобы гарантировать, что объекты создаются и уничтожаются амортизированным способом.

Аргумент, что iPhone ограничен в памятисреда истинна, но полная красная сельдь.Objective-C с платформами Foundation и Cocoa (хотя в то время их так не называли) выполнял просто отлично на NeXTcube, который имел 16 МБ ОЗУ (с возможностью расширения до 64).Даже iPhone 3, который на данный момент в значительной степени является EOL, имеет 128 МБ.

edit

Поскольку приложение iPhone представляет собой приложение на основе runloop, новый автоматический выпускбассейн будет создаваться и уничтожаться каждый раз, когда он вращается.Это четко определено в документации.Таким образом, единственные причины, по которым вам нужно было бы создать собственный пул автоматического выпуска:

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

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

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

edit # 2

ОК, оказывается, что есть a рекомендация избегать использования autorelease. НО эта рекомендация содержится в разделе «Распределение памяти разумно» раздела «Настройка производительности и отзывчивости» Руководства по программированию приложений для iOS.Другими словами, избегайте этого , если вы измеряете проблему производительности .А если серьезно: авто-релиз существует уже около 20 лет и прекрасно работает на компьютерах гораздо медленнее и более ограниченно, чем современные iDevices.

3 голосов
/ 16 февраля 2011

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

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

2 голосов
/ 16 февраля 2011

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

1 голос
/ 16 февраля 2011

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

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

1 голос
/ 16 февраля 2011

Зависит от того, имеется ли пул авто-релиза.Например, если вы используете объекты target-c в обратном вызове рендеринга AudioUnit (который вызывается из отдельного потока без пула автоматического выпуска), то ваши автоматически выпущенные объекты будут вытекать.В этом случае важно, чтобы вы освободили их вручную или поместили в пул автоматического выпуска.

В целом, я думаю, что это зависит от вас и вашего стиля кодирования

1 голос
/ 16 февраля 2011

Есть баланс.Это сильно зависит от ситуации.В этом конкретном случае, предполагая, что переменные barItem* являются долгоживущими иварами, избегать автоматического выпуска довольно близко к 100% бессмысленности, потому что набор будет зависать независимо от того, выпустите ли вы его сейчас или через две секунды.

На самом деле, в большинстве случаев не имеет большого значения, будут ли объекты освобождены сейчас или на следующей итерации цикла выполнения, потому что цикл запускается так быстро, что фактически способен создавать плавную анимацию .IPhone - это платформа, особенно нуждающаяся в памяти, поэтому хорошо не оставлять вещи живыми слишком долго.Но в то же время, будьте реалистами: один автоматически выпущенный NSNumber в методе, который вызывается каждые пару секунд, даже не повлияет на профиль вашего приложения.Даже 100-символьные строки NSStrings будут использовать только около 0,065% оперативной памяти на iPhone 3GS.Это становится значительным только тогда, когда вы создаете тонну из них за очень короткое время.Так что, если нет проблем, не парься.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...