クロージャを実現するために, コンパイラは裏側でクラスを作成します.
もしスマートフォン向けのアプリケーションを開発しているのならば,
これだけでも高いコストを支払っています.
かなり強引な例ですが, 以下のようなコードの場合を考えます.
Destroyボタンを押してから, Unloadボタンを押してもテクスチャは解放されません.
Clearボタンを押してから, Unloadボタンを押すことで解放されます.
クラスはどこかから参照されているかぎり, ガーベージコレクタによって削除されません.
明らかにLoaderの実装に欠点がありますが,
texture変数は, コード上ではスコープから外れて参照が切れているように見えてしまっている、
ことも問題です.
public class Loader : MonoBehaviour
{
private UnityEngine.Events.UnityAction onLoadFinish_;
private ResourceRequest request_;
public void load(string path, UnityEngine.Events.UnityAction onLoadFinish)
{
request_ = Resources.LoadAsync(path);
onLoadFinish_ = onLoadFinish;
}
public void clear()
{
onLoadFinish_ = null;
request_ = null;
}
void Update()
{
if(null != request_){
if(request_.isDone){
if(null != onLoadFinish_){
onLoadFinish_(request_.asset);
}
request_ = null;
}
}
}
}
public class Scene : MonoBehaviour
{
public Loader loader_;
public UnityEngine.UI.Button buttonDestroy_;
public UnityEngine.UI.Button buttonClear_;
public UnityEngine.UI.Button buttonUnload_;
public GameObject prefab_;
private GameObject instance_;
void Start()
{
buttonDestroy_.onClick.AddListener(onClickDestroy);
buttonClear_.onClick.AddListener(onClickClear);
buttonUnload_.onClick.AddListener(onClickUnload);
Texture2D texture;
loader_.load(
"image",
(UnityEngine.Object obj)=>
{
GameObject.Destroy(instance_);
instance_ = GameObject.Instantiate(prefab_);
instance_.transform.SetParent(transform);
texture = obj as Texture2D;
instance_.GetComponent().texture = texture;
});
}
void onClickDestroy()
{
GameObject.Destroy(instance_);
instance_ = null;
}
void onClickClear()
{
loader_.clear();
}
void onClickUnload()
{
Resources.UnloadUnusedAssets();
}
}
人それぞれですが, 私はこのコードが読みやすいとは思えません.
コールバックを多用する設計も奇麗とは思えません.
特にJavascript界隈でコールバック地獄と聞きますが,
わざわざ地獄に足を突っ込む必要はないと思います.
達人に刃物を持たせる分には一向に構わないのですが.
追記.
少し修正, でも強引過ぎるか.
0 件のコメント:
コメントを投稿