Утечки памяти - это самые противные ошибки. Как правило, их поиск сводится к тому, чтобы закомментировать разные участки кода и локализовать место утечки. Есть специальные инструменты, но и они далеко не всегда помогают быстро локализовать ошибку. Все равно придется помучиться.
Кстати, и тут создатели свифта нам помогли. У свифта есть чудесная особенность - можно делать вложенные комментарии, такие как
/*code
/* code */
code*/
Это очень сильно помогает в поиске ошибок. Даже не приходит в голову никакой другой популярный язык, где разрешались бы вложенные комментарии. Может, кто подскажет?
А самое трудное найти утечку памяти, которая возникает не всегда, а время от времени. Поэтому надо любыми способами избегать ситуаций, когда утечка может возникнуть.
У свифт-программиста, слава Богу, мало тонких мест, когда могут возникать утечки памяти. Навскидку:
- когда объекты ссылаются друг на друга циклически.
- когда замыкание захватывает ссылку на объект.
- когда сделали что-то вроде group.enter(), а group.leave() забыли.
Может, еще что-то, но не вспоминается из практики.
Эппл пытается нам помочь в каждом непростом случае. Например, вместо классов рекомендует использовать структуры, которые передаются by value, поэтому циклических ссылок возникнуть в структурах не может. В замыканиях требуется всегда писать явно self.myVar, это тоже не случайно.
Но и программисту нужно быть предельно внимательным, когда он понимает, что есть вероятность возникновения утечки памяти. Неважно, маленькая эта вероятность или большая. Если утечка возможна, этого достаточно, чтобы обложиться со всех сторон защитой, даже если вам кажется, что это смешно. Потом будет не смешно, когда вы и ваши коллеги днями и ночами будете комментировать код кусочками, пытаясь локализовать место утечки.
Поэтому, уважаемые форумчане, не слушайте всяких проходимцев, и крайне осторожно подходите к коду, который может вызвать утечку. Используйте структуры вместо классов, если это возможно. Избегайте замыканий (если это не функции), а если используете, пишите всегда [unowned self]. Всегда проверяйте на парность group.enter()/group.leave().
И как можно чаще нажимайте в Xcode кнопочку “Debug memory graph”. Кнопочка эта очень маленькая, но крайне полезная. Чем раньше вы найдете утечку, тем лучше.
Желаю всем поменьше ошибок в коде. И не болейте, берегите себя.