169 похожих чатов

Подскажите, че то туплю уже, если я из фрагмента передам

лямбду во вьюмодель и фрагмент будет хранить эту лямбду, при уничтожении фрагмента будет утечка? как передать лямбду и избежать утечку? я ее использую как подписку на определенный результат var isError: ((Boolean) -> Unit)? = null

36 ответов

14 просмотров

не очень понял что куда, но почему бы не дернуть метод у вьюмодели?

У вью модели подписываются на LiveData. Велосипед уже изобрели 😏

Turalllb-Turalll Автор вопроса

наоборот вьюмодель должна оповестить вьюху, дернуть метод нельзя тупо из-за общего дизайн стиля mvvm , как я понимаю

ну это в mvvm делается какой-нибудь лайфдатой насколько я знаю. Она лежит в вьюмоделе и пересозданный фрагмент на нее подписывается

Turalllb-Turalll Автор вопроса

liveData громоздкий, для одного единственного случая где он есть. Во всех случаях используется flow , но из-за того что collect работает только в корутин скоупе и этом конкретном случае мне нужна вот такая подписка.

Лямбда может захватывать объекты, например локальные переменные или сам фрагмент. Если фрагмент таким образом оставляет на себя ссылку внутри переживающей его вьюмодели, то чтобы не было утечек должен при разрушении занулить лямбду там, куда устанавливал. Всё как с подписками на события (это же те же делегаты, только кладутся в список).

В каком месте он громоздкий? VM обновляет значение, подписчик получает. Привязано к жц, ничего не течет. Хорошо же!

Turalllb-Turalll Автор вопроса

в том что это целая библиотека, а мне в единственном месте в целом приложении нужно вернуть результата в таком вот виде, везде в других местах мне хватает flow

Есть lifecycleScope

Turalllb-Turalll Автор вопроса

да, мне вот тоже самое говорят, только руками. В Свифте есть возможность помечать лямбду, чтобы она брала только слабые ссылки, в джава и котлин такого почему то нет. Наверно потому что сборщик мусора все равно сразу не сработает и оптимальнее сделать зануление руками.

Если и Flow не подходит, то тогда остаются только костыли 🤷‍♂ И все это ради сомнительной пользы от неиспользования импорта.

Установить переменную в onCreateView и занулить в onDestroyView это разве костыль?

Turalllb-Turalll Автор вопроса

у меня такая гнилая ситуация , что я в ui потоке присваиваю вьюмодели данные, полученные из arguments из другого фрагмента. При этом во вьюмодели в его корутин скоупе (чтобы не отменилось) происходит запрос в сеть. Если будет ошибка я должен оповестить, так как это его корутин скоуп, я не могу во вьюхе использовать try ибо ошибка из другого скопа не всплывет. И теперь мне нужно подписаться, если использовать флоу, то это снова корутина, исполнение которой может быть чуть позже , исполнения главного потока и я не увижу ошибку или увижу если это stateFLow, но тогда я буду видеть ее всегда и нужны лишние телодвижения, чтобы определить что я уже показывал эту ошибку.

Turalllb-Turalll Автор вопроса

вообще нет, стандартный removeListener

Он самый. Поэтому я себе базовый класс сделал, чтобы иметь этот функционал в одном месте под капотом вместе с inflate и забыть про inflate в каждом фрагменте.

Сделать передачу arguments во вьюмодель suspended fun, с ретёрном результата запроса, сам запрос обернуть в withContext(Dispatchers.IO) Метод вызывать соответственно в lifecycleScope

Объясните почему костыль? Это вроде самый классический вариант удержания ссылок на время жизни вьюхи. Ну и inflate же так под капотом фрагмента работает, нужно только в конструктор layout id передать.

Turalllb-Turalll Автор вопроса

не костыль, просто удобнее если это автоматом происходит

Упс, я ответил в контексте ViewBinding + Fragment.

Кстати, считаю, что delegated property лучше подходит под интеграцию ViewBinding, чем наследование фрагмента. Пример, о чем я.

Я сделал так, что мне достаточно написать следующее: class MyFragment : MyBaseFragment<MyFragmentBinding>() { ... val binding доступен из базового класса. Задолбало каждый раз делать by что-то, указывать ресурс лэйаута и тут же его view binding.

Turalllb-Turalll Автор вопроса

этот вариант тоже не подходил, потому что пока вьюмодель не получила это значение, вьюха не должна была дальше исполнять код, блокировать вьюху не красиво. Но видно что вы меня максимально поняли, спасибо)

А вьюмодель как подключаете?

Пока как обычно, by viewModels или типа того. Это не требует большого количества телодвижений. А что?

Интересен чужой опыт) показалось, что и by viewModels задолбало

А как вы базовый биндинг приводите к тому, который вам нужен во фрагменте?

Кстати, да

Я тут про это пару дней назад рассказывал. Поищите по слову колдунство 😁

Поняяятно. После такой черной магии называете зануление ссылок в onDestroyView костылями?)

Я сказал только, что лучше использовать LiveData, чтобы получать уведомления из VM. Нормальный механизм же, специально для этого придуманный.

Я если честно в контекст не вникал, увидел что - то про биндинг в базовом классе и прост влетел, пока сборка собирается.

Чего только не придумают чтобы побороть viewbinding RIP kotlin synthetics🕯

Для уведомления о состоянии - да, более менее, но у автора вопроса, в контексте которого мы ведём обсуждение, требуется срабатывать одноразовому событию. Адепты лайвдаты для такого мастерят те самые SingleLiveEvent. Автор решил использовать самый базовый и понятный способ - просто передать делегат в свойство.

А потом фрагмент умер и началось веселье.

Опять по новой)

Шо поделать! Народу нравится танцевать на граблях 😁

Похожие вопросы

Обсуждают сегодня

Сообщение* в закодированном виде. То есть, просто сделать sendMessage?text=Привет бла-бла! не получится, надо в HEX переводить, и добавлять процент, типа такого: sendMessage?t...
КТ315
21
Anyone here suffers from unexplained aural migraines, who would be up for talking for a bit? Doesn't *have* to be aural, but I am not asking about headaches, I mean actual mi...
Martin Rys
58
А случайно нет ли в паскале штатной возможности передать указатель и количество туда где array of в качестве аргумента?
zamtmn
25
> комьюнити я бы не судил по этому чату. Как мы видели по статам просмотров нескольких телеговских постов, то в чате их набивается 30-40 или даже выше, когда как общаются акти...
Constantin F.
4
приветы , подскажите что я не так сделал , почему у меня скрипт не работает в программе Revit ? ;Autohotkey_RU IfWinActive ("ahk_exe Revit.exe") ; только в открытом Revit Gu...
Anton Terentev
2
Ну раз я пока тут, задам пару глупых вопросов. Зачем писать на ассемблере если компилятор довольно умный, а ассемблер много времени занимает? В каких прикладных задачах сейчас...
Максим Рябцев
20
Как сделать чтобы short точно был 2 байта, int точно 4 байта ?(без стандартных библиотек, ну типа без int16_t, int32_t)
#
8
Всем привет. Испытываю проблемы в работе БД, а именно огромного роста логов, такого характера: 024-05-16 18:39:07 +05 sentry sentry [unknown] 1050169 7-1 app-sentry01.corp.ru>...
Alexey
2
Почему Telegram пишет, что объект media не найден, хотя на самом деле я его передаю? Делаю на urllib, без зависимостей, так надо. Вызываю метод sendMediaGroup с таким JSON: ...
Alexey S
1
Хм. А телеграм апи работают через HTTP?
The Bird of Hermes
14
Карта сайта