Каковы наилучшие методы предотвращения утечек при использовании блоков objective-c? - программирование

Каковы наилучшие методы предотвращения утечек при использовании блоков objective-c?

Я некоторое время работал с блоками, и я стараюсь быть в курсе всех возможных сценариев. Я много читал о "циклах цикла сохранения", но я думаю, что, возможно, есть и другие возможные сценарии. Кроме того, я думаю в некоторых простых случаях, например: Что делать, если вы вызываете блок внутри блока?; Различается ли управление блочной памятью, если мы используем ARC или нет?; как найти, блокирует ли блок память с помощью инструментов (или какого-то другого инструмента)?

4b9b3361

Ответ 1

Краткий ответ: блоки не по своей сути не вносят никаких особых проблем с утечкой (кроме сохранения циклов в особых обстоятельствах, описанных ниже).

Длинный ответ: пара мыслей:

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

    Как обсуждалось в использовать пожизненные квалификаторы, чтобы избежать сильных опорных циклов, в MRC вы можете использовать квалификатор __block для решения этих сильных, но в ARC вы можете использовать квалификатор __weak.

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

  • Блоки сохраняют объекты, которые они ссылаются (если только объект не квалифицирован, например, с __block в MRC или с __weak в ARC). Тот факт, что один использует блоки, не влияет на то, протекает ли код или нет. Это функция вашего выбора ARC v MRC и избегали ли вы сохранения циклов и, если вы делаете MRC, включили ли вы необходимые операторы release.

  • С точки зрения обнаружения утечек стандартные инструменты работают нормально:

    • Особенно, если вы используете код без ARC, статический анализатор (shift + command + B или выберите "Анализ" в меню "Продукт" ) очень полезен.

    • Обсуждение Поиск утечек в вашем приложении в руководстве пользователя Instruments.

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

    • Если вам интересно, правильно ли освобожден какой-либо объект, полезно добавить диагностическую реализацию dealloc к вашему объекту, который должен быть выпущен:

      - (void)dealloc
      {
          NSLog(@"%s", __FUNCTION__);
      
          // if non-ARC, remember to include the following line, too:
          //
          // [super dealloc];
      }
      

      Таким образом, вы увидите сообщение на консоли, когда объект будет освобожден.

  • Если вас беспокоит утечка, использование ARC - это (ИМХО) один из самых простых способов устранения многих мирских утечек. Невероятно легко протекать в коде без ARC с простыми пропущенными release или autorelease (хотя, по общему признанию, вышеупомянутые ссылки помогут вам найти их). В ARC гораздо труднее просочиться из-за простого "о, я забыл release".

Ссылки