На практике, ложноположительные срабатывания могут быть, если модель очень сложная и разветвлённая, со множеством вложенных объектов и зависимостей. Мы заметили, что для того, чтобы полностью её освободить может не хватать дефолтной задержки в одну секунду. Собственно, этим и объясняется наличие опционального параметра задержки у враппера.
В остальных случаях, когда модель по каким-то причинам создаётся не один раз и предыдущий экземпляр не освобождается, мы уже не можем считать, что срабатывание было ложным.
Если посмотреть предложенные ссылки, там всё сводится как раз к такой ситуации. Относительно LazyVStack и им подобным, это – известная проблема. Похожее поведение будет и в UIKit, если модель UITableViewCell создавать внутри самого объекта UITableViewCell.
Для примеров в статье был выбран StateObject из соображений компактности примеров. В архитектуре реального проекта, использование StateObject не представляется оправданным, т.к. это не соответствует понятиям чистой архитектуры и SOLID. Проще говоря, мы не используем StateObject вообще, все модели у нас – ObservableObject, которые создаются однократно, вне скоупа SwiftUI. Соответственно, при переиспользовании View, они получают одну и ту же ссылку на один и тот же объект.
А Вы не замеряли, есть ли заметные накладные расходы по производительности при использовании этого подхода?
Какие-то расходы есть, конечно, но они не сравнимы с последствиями утечки
Насколько часто Вы пользуетесь этими аннотациями? Только для ViewModel или для каких-то более мелких объектов тоже?
В основном – для моделей. Обычно, если "утекает" что-то мелкое внутри модели – сама модель тоже не освобождается. Однако, ограничений нет.
Вы оставляете эти проверки в release-версии?
Нет, в реальном коде проверки закрыты аннотациями #if DEBUG || ADHOC
Но ведь не совсем? Instruments позволяет именно обнаружить утечки, они "подсвечиваются" по ходу работы приложения. Или применительно к SwiftUI этот инструмент работает не очень хорошо? Я в SwiftUI пока не пробовал им пользоваться.
В самом Xcode примерно также, только нужно останавливать выполнение. Однако, не это главное. В описанном варианте утечку может обнаружить QA-инженер, тестирующий на реальном устройстве, а не только разработчик в Xcode/Instruments, когда специально этим озаботится. Разработчик может спокойно писать код, зная, что утечки будут найдены в процессе тестирования.
На практике, ложноположительные срабатывания могут быть, если модель очень сложная и разветвлённая, со множеством вложенных объектов и зависимостей. Мы заметили, что для того, чтобы полностью её освободить может не хватать дефолтной задержки в одну секунду. Собственно, этим и объясняется наличие опционального параметра задержки у враппера.
В остальных случаях, когда модель по каким-то причинам создаётся не один раз и предыдущий экземпляр не освобождается, мы уже не можем считать, что срабатывание было ложным.
Если посмотреть предложенные ссылки, там всё сводится как раз к такой ситуации. Относительно LazyVStack и им подобным, это – известная проблема. Похожее поведение будет и в UIKit, если модель UITableViewCell создавать внутри самого объекта UITableViewCell.
Для примеров в статье был выбран StateObject из соображений компактности примеров. В архитектуре реального проекта, использование StateObject не представляется оправданным, т.к. это не соответствует понятиям чистой архитектуры и SOLID. Проще говоря, мы не используем StateObject вообще, все модели у нас – ObservableObject, которые создаются однократно, вне скоупа SwiftUI. Соответственно, при переиспользовании View, они получают одну и ту же ссылку на один и тот же объект.
Какие-то расходы есть, конечно, но они не сравнимы с последствиями утечки
В основном – для моделей. Обычно, если "утекает" что-то мелкое внутри модели – сама модель тоже не освобождается. Однако, ограничений нет.
Нет, в реальном коде проверки закрыты аннотациями #if DEBUG || ADHOC
В самом Xcode примерно также, только нужно останавливать выполнение. Однако, не это главное. В описанном варианте утечку может обнаружить QA-инженер, тестирующий на реальном устройстве, а не только разработчик в Xcode/Instruments, когда специально этим озаботится. Разработчик может спокойно писать код, зная, что утечки будут найдены в процессе тестирования.
Если объект LeakingViewModel "утечёт" – его deinit не будет вызван, соответственно, проверка не состоится.