siroponnだ。久しぶりだな。大丈夫私は生きているぞ。
今回もUE4についてだ。正直何でこのツールを皆使っているのか毎回疑問に思う。
頭が良くないと使えないように思えるが。皆頭良すぎだろ。
さて、本題に入ろう。
UE4のGCについてだ。詳しくはUObjectを継承したオブジェクトのGCについてだ。
先日このようなコードを書いた.
class Jyaian : UObject
{
GENERATE_UCLASS_BODY()
略
}
UCLASS(BlueprintType)
class Akiti : UObject
{
GENERATE_UCLASS_BODY()
Jyaian jyaian;
略.
}
Akiti::GenerateJyaian()
{
jyaian = NewObject<Jyaian>();
}
かなり簡略化しているが、おおむねこんな感じだ。NewObjectで生成してそれの参照を定義した変数に参照を持たせている。
このように、参照を持っているのであれば一般的にオブジェクトはGCの対象にならない。
しかし。これではjyaianオブジェクトはGC送りにされ、思わぬところで例外が発生する。jyaian死んじゃいやーん。
………。
どうやら、UE4では少し勝手が違うらしい。
UE4上でUObjectを継承したクラスへの参照をメンバ変数で持つ場合は
UCLASS(BlueprintType)
class Akiti : UObject
{
GENERATE_UCLASS_BODY()
UPROPETY()
Jyaian jyaian;
略.
}
をするのが正解だ。UPROPETYを付けるのである。こうすると、参照がある間は勝手に掃除されなくなる。
確かにエンジンのソースコードを読んでもこのようにしている箇所がチラホラ見受けられる。
何でだろうと思っていたが、少し納得した。
他にもNewObjectするときにフラグを設定でき,RF__RootSetを付ければGCされなくなると書いてあるが。これって明示的に自分で壊さないといけないってことだよね。リークが怖い。
そして以下が参考文献である。
https://wiki.unrealengine.com/Garbage_Collection_%26_Dynamic_Memory_Allocation#Preventing_Garbage_Collection
ガッツリUPROPETY付けろって書いてありますね。これ、滅茶苦茶重要なのでは。
ドキュメントの目立つ場所に書いておいてくれないかな。
さて、今回はこんな感じだ。一人でも多くの人が、この罠に引っかからない事を祈りつつ。じゃあねノシ