2017年3月13日月曜日

UE4のUObjectを継承したオブジェクトについて

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付けろって書いてありますね。これ、滅茶苦茶重要なのでは。
ドキュメントの目立つ場所に書いておいてくれないかな。


さて、今回はこんな感じだ。一人でも多くの人が、この罠に引っかからない事を祈りつつ。じゃあねノシ

0 件のコメント:

コメントを投稿