лямбду во вьюмодель и фрагмент будет хранить эту лямбду, при уничтожении фрагмента будет утечка? как передать лямбду и избежать утечку? я ее использую как подписку на определенный результат var isError: ((Boolean) -> Unit)? = null
не очень понял что куда, но почему бы не дернуть метод у вьюмодели?
У вью модели подписываются на LiveData. Велосипед уже изобрели 😏
наоборот вьюмодель должна оповестить вьюху, дернуть метод нельзя тупо из-за общего дизайн стиля mvvm , как я понимаю
ну это в mvvm делается какой-нибудь лайфдатой насколько я знаю. Она лежит в вьюмоделе и пересозданный фрагмент на нее подписывается
liveData громоздкий, для одного единственного случая где он есть. Во всех случаях используется flow , но из-за того что collect работает только в корутин скоупе и этом конкретном случае мне нужна вот такая подписка.
Лямбда может захватывать объекты, например локальные переменные или сам фрагмент. Если фрагмент таким образом оставляет на себя ссылку внутри переживающей его вьюмодели, то чтобы не было утечек должен при разрушении занулить лямбду там, куда устанавливал. Всё как с подписками на события (это же те же делегаты, только кладутся в список).
В каком месте он громоздкий? VM обновляет значение, подписчик получает. Привязано к жц, ничего не течет. Хорошо же!
в том что это целая библиотека, а мне в единственном месте в целом приложении нужно вернуть результата в таком вот виде, везде в других местах мне хватает flow
Есть lifecycleScope
да, мне вот тоже самое говорят, только руками. В Свифте есть возможность помечать лямбду, чтобы она брала только слабые ссылки, в джава и котлин такого почему то нет. Наверно потому что сборщик мусора все равно сразу не сработает и оптимальнее сделать зануление руками.
Если и Flow не подходит, то тогда остаются только костыли 🤷♂ И все это ради сомнительной пользы от неиспользования импорта.
Установить переменную в onCreateView и занулить в onDestroyView это разве костыль?
у меня такая гнилая ситуация , что я в ui потоке присваиваю вьюмодели данные, полученные из arguments из другого фрагмента. При этом во вьюмодели в его корутин скоупе (чтобы не отменилось) происходит запрос в сеть. Если будет ошибка я должен оповестить, так как это его корутин скоуп, я не могу во вьюхе использовать try ибо ошибка из другого скопа не всплывет. И теперь мне нужно подписаться, если использовать флоу, то это снова корутина, исполнение которой может быть чуть позже , исполнения главного потока и я не увижу ошибку или увижу если это stateFLow, но тогда я буду видеть ее всегда и нужны лишние телодвижения, чтобы определить что я уже показывал эту ошибку.
вообще нет, стандартный removeListener
Он самый. Поэтому я себе базовый класс сделал, чтобы иметь этот функционал в одном месте под капотом вместе с inflate и забыть про inflate в каждом фрагменте.
Сделать передачу arguments во вьюмодель suspended fun, с ретёрном результата запроса, сам запрос обернуть в withContext(Dispatchers.IO) Метод вызывать соответственно в lifecycleScope
Объясните почему костыль? Это вроде самый классический вариант удержания ссылок на время жизни вьюхи. Ну и inflate же так под капотом фрагмента работает, нужно только в конструктор layout id передать.
не костыль, просто удобнее если это автоматом происходит
Упс, я ответил в контексте ViewBinding + Fragment.
Кстати, считаю, что delegated property лучше подходит под интеграцию ViewBinding, чем наследование фрагмента. Пример, о чем я.
Я сделал так, что мне достаточно написать следующее: class MyFragment : MyBaseFragment<MyFragmentBinding>() { ... val binding доступен из базового класса. Задолбало каждый раз делать by что-то, указывать ресурс лэйаута и тут же его view binding.
этот вариант тоже не подходил, потому что пока вьюмодель не получила это значение, вьюха не должна была дальше исполнять код, блокировать вьюху не красиво. Но видно что вы меня максимально поняли, спасибо)
А вьюмодель как подключаете?
Пока как обычно, by viewModels или типа того. Это не требует большого количества телодвижений. А что?
Интересен чужой опыт) показалось, что и by viewModels задолбало
А как вы базовый биндинг приводите к тому, который вам нужен во фрагменте?
Кстати, да
Я тут про это пару дней назад рассказывал. Поищите по слову колдунство 😁
Поняяятно. После такой черной магии называете зануление ссылок в onDestroyView костылями?)
Я сказал только, что лучше использовать LiveData, чтобы получать уведомления из VM. Нормальный механизм же, специально для этого придуманный.
Я если честно в контекст не вникал, увидел что - то про биндинг в базовом классе и прост влетел, пока сборка собирается.
Чего только не придумают чтобы побороть viewbinding RIP kotlin synthetics🕯
Для уведомления о состоянии - да, более менее, но у автора вопроса, в контексте которого мы ведём обсуждение, требуется срабатывать одноразовому событию. Адепты лайвдаты для такого мастерят те самые SingleLiveEvent. Автор решил использовать самый базовый и понятный способ - просто передать делегат в свойство.
А потом фрагмент умер и началось веселье.
Опять по новой)
Шо поделать! Народу нравится танцевать на граблях 😁
Обсуждают сегодня