Ответ
Метод deinit вызывается на том же потоке, где была удалена последняя сильная ссылка на объект. Это поведение не гарантируется системой и зависит от контекста использования объекта.
Пример:
class MyClass {
deinit {
print("Deinit on thread: (Thread.current)")
}
}
DispatchQueue.global().async {
let object = MyClass() // Создание в фоновом потоке
// object выходит из области видимости здесь
// deinit будет вызван в этом же фоновом потоке
}
Важные нюансы:
- Нет гарантии немедленного вызова:
deinitможет быть вызван не сразу после выхода объекта из области видимости, а позже, когда сработает сборщик мусора (ARC). - Циклические ссылки: Если объект участвует в цикле сильных ссылок (strong reference cycle),
deinitне будет вызван никогда, что приводит к утечке памяти. - Опасность deadlock: Внутри
deinitследует избегать синхронных вызовов (sync) на текущий поток, так как это может привести к взаимной блокировке. - Работа с потокобезопасностью: Поскольку поток вызова неизвестен заранее, любой доступ к общим ресурсам или UI из
deinitдолжен быть должным образом синхронизирован.