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

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

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

36 ответов

31 просмотр

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

У вью модели подписываются на 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. Автор решил использовать самый базовый и понятный способ - просто передать делегат в свойство.

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

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

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

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта