Почему не работает таймер в Swift?

Предположим, вы сделали

и отправились по своим делам, а таймер отработал один раз или вообще не отработал. Почему? А потому, что объект timer зажевал сборщик мусора, а при деинициализации DispatchSourceTimer, разумеется, останавливает своё дальнейшее выполнение. Напомню, сборщик мусора всегда отрабатывает в конце области выполнения, то есть, в данной ситуации, по окончанию блока, переданного в async. Таким образом, если вы хотите регулярно выполнять какую-то задачу, необходимо класть указатель на объект таймера в известное глобальное место, которое проживет столько, сколько захочется вам, а не сборщику мусора. Желательно также организовать синхронный и потоко-безопасный доступ к этому месту с помощью последовательной очереди выполнения, чтобы избежать постыдных гонок за доступ.

Кстати, следует отметить, что существует и обратная ситуация: таймер отказывается удаляться, когда вы удалите все ссылки на него. Это может быть оттого, что хендлер таймера может держать сильную ссылку на какой-нибудь класс или self. Чтобы этого избежать, указывайте [weak self] в начале хендлера таймера.

Теги: программирование, swift