Sound захвачен по ссылке, а ссылка оказывается битой когда таймер вызывает лямбду
Да, может быть. Надо глубокое копирование что ли...
Просто захвати по значению ([=]). Тут у тебя только указатели и float, так что копирование ничего не стоит
Да я пока не совсем понял что делает функтор, что такое пустая ссылка [&] и как передавать параметры в лямбде, а не в функции делегатаю...
А, типа функтора два: [&] - по ссылке, [=] - по значению?
Функтор это, грубо говоря, сама лямбда. [] - это Capture list, в нем перечисляются переменные, которые должны быть захвачены из области видимости, в которой объявляется лямбда. Да, захватить можно по ссылке и по значению. Желательно захватывать только те переменные, которые тебе нужны
Спасибо, уже понятнее, а как указать в Capture List переменные?
[&VariableName, VariableName2] Такую инфу уже лего найти по первой ссылке в гугле
Тут как я понял, нужно передать ссылку на сам класс чтобы использовать переменную MainAudio. А если в функторе указывается просто [=], в этом случае функция сама вычисляет что нужно передать?
У тебя тут 2 ошибки: 1 - this может быть уже не валидным, когда вызовется делегат, 2 - MainAudio может так-же быть не валидным, так что это потенциально 2 креша.
Да, надо гасить таймеры в BeginDestroy()
MainAudio в гейм инстанс подсистеме и по идее жив на протяжении всего жизненного цикла, но тем не менее можно сделать так:
Нет, не в деструкторе. Деструктор для другого создан. На EndPlay обычно лучше их прибивать.
Накануне как раз выше обсуждали, нужны ли деструкторы для таймеров или нет... Один чел сказал что делегат собирается GC после дестроя объекта, я посмотрел по коду - уничтожается он только после истечения таймера, а если зациклен - надо руками чистить.
А еще лучше проверять валидность класса, в котором вызывается Лямбда. Просто представь, у тебя класс уже не валиден, но лямбда вызывается. Но это так, к слову. Вот пример Эпиков.
Я всегда чистю всё, причем чем раньше - тем лучше. BeginDestroy намного позже вызывается, чем даже пометка флагом RF_PendingKill Я бы все привязывал бы к EndPlay, так надежнее. https://docs.unrealengine.com/4.26/en-US/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Actors/ActorLifecycle/
Ну для гейминстансов и их подсистем это имеет смысл?
Да, смотри, то, что они живут долго не отменяет того, что при выходе из игры игрок словит креш (опять-же, теоретически). Вопрос в том, что ты не можешь знать точно, когда и что будет уничтожено. Более того, я бы не стеснялся бы проверять объекты через IsValid. Потому, что если объект уже начал уничтожаться, то if (SomeObject) пройдет, но вот далее потенциальный креш.
Спасибо! То есть достаточно будет проверки if (IsValid(this)), а мягкие указатели использовать не обязательно.
Да, но, речь шла не о SoftPointers, а о том, что в Лямбдах с отложенным исполнением ты никогда не можешь гарантировать ни то, что класс, где эта лямбда будет выполнена еще валиден, ни то, что всё, что ты там используешь еще валидно. По этому да, лучше перестраховаться и проверять всё. Или глянь BindWeakLambda, тут в теории уже не нужно доп. проверок на валидность класса, но IsValid(MainAudio) - нужно.
Обсуждают сегодня