Почему автореферат особенно опасен / дорого для приложений iPhone?

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

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

Ссылки:
autorelease-iphone
Почему это создает утечку памяти (iPhone)?

Примечание. С концептуальной точки зрения я вижу, что autorelease немного дороже простого вызова для release , но я не думаю, что этого достаточно, чтобы Apple рекомендовала против него.

Какая история?

(не можете принять свой собственный ответ?)

Ну, после всего этого мне удалось найти ссылку от Apple Developer, добавленную в виде боковой заметки в нижней части страницы:

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

Тем не менее, это предполагает использование autorelease тщательно, не избегая его в целом.

(и теперь для моего комментария)

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

Речь не идет о том, чтобы использовать или не использовать autorelease, потому что в некоторых случаях autorelease – это единственный способ, которым вы пройдете. Вопрос должен быть « Почему бы не использовать autorelease на всех объектах, а не использовать сохранение и выпуск? ».

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

 - (NSString *) fullName { NSString str = [[NSString alloc]initWithFormat:@"%@ %@", firstName, lastName]; // this is not good until we put [str autorelease]; return str; } 

Что случилось с этой картиной? Счетчик ссылок на возвращаемую строку равен 1, поэтому, если вы не хотите течь, вызывающий должен освободить его, когда он закончит. С точки зрения вызывающего, он просто запросил значение свойства fullName . Он не знает о том, что у него появился новый объект, который он должен опубликовать после использования, а не какую-то ссылку на NSString, внутренне удерживаемую classом!

Если мы поместим [str release] перед возвратом, строка будет уничтожена, и метод вернет мусор! Вот где мы используем [str autorelease] , чтобы пометить объект для выпуска позже (обычно, когда обработка событий завершена). Таким образом, вызывающий получает свой объект, и ему не нужно беспокоиться о том, должен ли он освободить его или нет.

Соглашение заключается в вызове autorelease на новый объект, прежде чем метод вернет его вызывающему. Исключениями являются методы с именами, которые начинаются с alloc , new или copy . В таких случаях вызывающие абоненты знают, что для них создан совершенно новый объект, и их обязанность заключается в вызове release на этом объекте.

Замена релиза с авторекламой – это плохая идея, так как объекты будут накапливаться и забивать память очень быстро, особенно в циклах. Ресурсы на iPhone ограничены, поэтому, чтобы свести к минимуму засорение памяти, ваша задача – освободить объект, как только вы закончите с ним.

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

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

Autorelease не заменяет сборку мусора (недоступно в iPhone SDK) и может привести к неприятным ошибкам в указательных указателях (указатель по-прежнему кажется хорошим, а затем в какой-то непредсказуемый момент недействителен), но также очень полезен в письменной форме четкий и простой в обслуживании код. Рассмотрим следующий случай:

 [aDictionary writeToFile: [documentsDirectory stringByAppendingPathComponent:@"settings.plist"] atomically:YES]; 

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

Я согласен с вышеупомянутым плакатом, что следующая конвенция и последовательное – это очень хорошая идея.

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

Как подчеркивается Apple, особая область, вызывающая озабоченность, заключается в том, что вы используете автореализованные объекты в любом виде цикла, потому что они накапливаются в пуле автозаполнения. Затем вам нужно управлять, когда сливать пул или создавать / выпускать его. Выполнение каждого прохода через цикл может ухудшить производительность, но слишком много проходов не приведет к опасному использованию памяти. Я по-прежнему настраиваю это в Molecules, потому что при импорте больших (> 2 МБ) текстовых файлов из банка данных протеина возникают проблемы с прерывистой памятью. Я смог улучшить производительность, минимизируя автореализованные объекты, но не смог полностью их устранить.

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

Я бы очень хотел избегать авторекламы, как чумы. Ошибки управления памятью – отличный способ тратить огромное количество времени и денег, у меня была сомнительная честь многократно проходить этот процесс на старых Mac-приложениях, а тот факт, что iPhone имеет ограниченные ограничения памяти, означает, что у вас есть быть очень осторожным, или приложение будет просто неустойчивым и часто случается с ошибкой … как и многие из первых приложений, выпущенных летом прошлого года.

Единственным надежным способом, который я нашел для написания стабильных приложений для iPhone, является управление всей вашей памятью самостоятельно и последовательное выполнение. Даже если вы являетесь единственным программистом в своем проекте, вы поблагодарете себя позже. Это может быть трудно, если вы научились программировать на языках, которые «заботятся обо всем для вас», но действительно стоит узнать, как преуспеть, если вы серьезно относитесь к созданию качественных приложений для iPhone.

Interesting Posts
Давайте будем гением компьютера.