クロージャを実現するために, コンパイラは裏側でクラスを作成します.
もしスマートフォン向けのアプリケーションを開発しているのならば,
これだけでも高いコストを支払っています.
かなり強引な例ですが, 以下のようなコードの場合を考えます.
Destroyボタンを押してから, Unloadボタンを押してもテクスチャは解放されません.
Clearボタンを押してから, Unloadボタンを押すことで解放されます.
クラスはどこかから参照されているかぎり, ガーベージコレクタによって削除されません.
明らかにLoaderの実装に欠点がありますが,
texture変数は, コード上ではスコープから外れて参照が切れているように見えてしまっている、
ことも問題です.
public class Loader : MonoBehaviour { private UnityEngine.Events.UnityActiononLoadFinish_; 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 件のコメント:
コメントを投稿