2016-05-22 3 views
2

Я изучаю возможные ловушки утечки памяти в iOS, и я продолжаю сталкиваться с сильными ссылочными циклами. Это стало ясным, и единственное, о чем я упоминал, что я могу найти в отношении утечек памяти, даже в Apple's documentation.Возможные причины утечек памяти в iOS?

Каковы некоторые другие причины утечек памяти?

+0

Вы первоначально помеченный этот вопрос как с Objective-C и Swift теги. Существуют категории проблем, которые поражают Objective-C код, который редко или вообще не существует в Swift. Существуют и другие проблемы, общие для обоих. Будучи немного более конкретным языком и/или типами операций, которые вы выполняете, мы можем быть более конкретными в нашем совете. – Rob

ответ

5

В Objective-C, существует много типов утечек, что статический анализатор (сдвига - Команда - В) может помочь идентифицировать. Помимо простых сильных эталонных циклов, если вы не используете ARC с Objective-C, очень легко протекать. И если вы используете объекты Core Foundation (особенно в Objective-C) и не будете осторожны, вы можете легко протечь. Статический анализатор довольно хорошо идентифицирует многие из этих простых проблем.

Но отступив немного, Apple обсуждает три типа общих проблем памяти:

  • просочилась памяти: память, которая не может быть доступны снова.

    Примеры этого было бы неправильно шунтирующий типов ядра Foundation, сильные опорные циклы и т.д.

  • Заброшенный памяти: Память, не доступ снова.

    Примером этого может служить циркулярная ссылка в виде контроллеров (от A до B и до A снова, вместо того, чтобы выскакивать/отклоняться назад до A). Оригинальный контроллер зрения по-прежнему существует, и теоретически может получить доступ к своим объектам, но вы никогда не будете делать это, потому что вы в настоящее время работаете с новым экземпляром А.

  • Сохраненных памятями: память, которая может (но для которого вы можете или не можете получить к нему доступ еще раз).

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

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

Я предлагаю смотреть несколько WWDC видео, включая:

+2

Приятное прикосновение, объясняющее разницу между утечкой и заброшенной памятью. (Голосов) –

3

Есть четыре основных случая:

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

    Это может произойти более легко, чем вы могли предположить. Действительно, в моей реальной жизни самыми трудными случаями являются ситуации, когда нормальное использование Какао создает цикл удержания, и вы этого не осознаёте. Примерами являются регистрация NSNotificationCenter с объектом-наблюдателем и WKUserContentController WebKit (как я обсуждаю here).

  • Если вы используете Objective-C с ARC, дополнительная проблема заключается в том, что вы можете неправильно использовать CFTypeRefs. Освобождение их зависит от вас, и вы можете забыть/не сделать этого. (Эта проблема не может возникнуть, если вы используете Swift, потому что Swift управляет CFTypeRefs для вас.)

  • Если вы используете Objective-C без ARC (что было бы очень глупо из вас), вы можете портить любой объект, поэтому практически все, что вы создаете, может протекать.

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

+0

Наши ответы были почти идентичны, но вы избили меня до удара! :) Однако вы не упомянули память malloc'ed. –

2

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

ARC не управляет памятью памяти, которая выделяется с помощью malloc/calloc. Это полностью зависит от вас. Если вы malloc блок памяти, вы должны освободить его, когда вы сделали с ним, или он просочился.

ARC также не управляет памятью Core Foundation Objects, если только вы не используете правильные мосты для ручного управления этими объектами в Cocoa. Поэтому, если вы CFCreate объект Core Foundation, а затем не CFRelease, вы также просто пропустили память.