zoukankan      html  css  js  c++  java
  • 消息机制的优化----------无需进行装箱/拆箱的 版本

    消息机制的优化----------无需进行装箱/拆箱的  版本

    http://www.manew.com/thread-111056-1-1.html

    装箱/拆箱
    为了解释“为什么不用object传递参数?”先简单介绍一下“装箱/拆箱”,请看下面代码:

    [C#] 纯文本查看 复制代码
    int a = 10;
    object b = a; //装箱
    a = (int)b; //拆箱


    第二行,会在堆上实例化一个装箱的对象,并把a的值复制进去,b 引用的就是这个对象。
    第三行,会再次进行值复制,若 b 不再引用,则需等待垃圾回收。


    常见的事件管理器
    我们看一些常见的事件管理器使用代码:

    [C#] 纯文本查看 复制代码
    void Start()
    {
        //注册事件
        EventManager.AddEventListener("Click", OnClick);
    }

    public void OnClick(object data)
    {
        Debug.Log("clickBlock: " + data);
    }

    //派发事件
    EventManager.dispatchEvent("Click", 123);


    如上所述,若传递的是引用类型则不会有影响。但如果传递的是值类型,就会产生上述的性能消耗。


    泛型优化
    我们可以通过泛型去设置参数的类型,从而不需要通过 object 类型传递参数:

    [C#] 纯文本查看 复制代码
    public void Dispatch<T1, T2, T3, T4>(string evt, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
    {
        Delegate[] methods = GetMethods(evt);
        if (methods != null)
        {
            foreach (Delegate m in methods)
            {
                try
                {
                    ((Action<T1, T2, T3, T4>)m)(arg1, arg2, arg3, arg4);
                }
                catch (Exception e) { LogError(e); }
            }
        }
    }


    将上面的代码,改为用泛型事件管理器:

    [C#] 纯文本查看 复制代码
    void Start()
    {
        //注册事件
        EventDispatcher.global.AddListener<int>("Click", OnClick);
    }

    public void OnClick(int data)
    {
        Debug.Log("clickBlock: " + data);
    }

    //派发事件
    EventDispatcher.global.Dispatch<int>("Click", 123);


    另:该事件管理器还支持【继承】与【实例化】,因此可以在非脚本对象和派生自MonoBehaviour的实例中使用。

    完整代码:

    本帖隐藏的内容

    [C#] 纯文本查看 复制代码
    /*
    * Author:  Rick
    * Create:  2017/11/21 16:47:25
    * Email:   rickjiangshu@gmail.com
    * Follow:  https://github.com/RickJiangShu
    */
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// 事件派发器
    /// 1. 优化装箱/拆箱
    /// 2. 不使用闭包
    /// </summary>
    public class EventDispatcher
    {
        public static EventDispatcher global
        {
            get;
            private set;
        }
        static EventDispatcher()
        {
            global = new EventDispatcher();
        }

        private Dictionary<string, Delegate> _listeners = new Dictionary<string, Delegate>();

        public void AddListener<T1, T2, T3, T4>(string evt, Action<T1, T2, T3, T4> callback)
        {
            AddListener(evt, (Delegate)callback);
        }
        public void AddListener<T1, T2, T3>(string evt, Action<T1, T2, T3> callback)
        {
            AddListener(evt, (Delegate)callback);
        }
        public void AddListener<T1, T2>(string evt, Action<T1, T2> callback)
        {
            AddListener(evt, (Delegate)callback);
        }
        public void AddListener<T>(string evt, Action<T> callback)
        {
            AddListener(evt, (Delegate)callback);
        }
        public void AddListener(string evt, Action callback)
        {
            AddListener(evt, (Delegate)callback);
        }
        public void AddListener(string evt, Delegate callback)
        {
            Delegate listener;
            if (_listeners.TryGetValue(evt, out listener))
            {
                _listeners[evt] = Delegate.Combine(listener, callback);
            }
            else
            {
                _listeners[evt] = callback;
            }
        }

        public void RemoveListener<T1, T2, T3, T4>(string evt, Action<T1, T2, T3, T4> callback)
        {
            RemoveListener(evt, (Delegate)callback);
        }
        public void RemoveListener<T1, T2, T3>(string evt, Action<T1, T2, T3> callback)
        {
            RemoveListener(evt, (Delegate)callback);
        }
        public void RemoveListener<T1, T2>(string evt, Action<T1, T2> callback)
        {
            RemoveListener(evt, (Delegate)callback);
        }
        public void RemoveListener<T>(string evt, Action<T> callback)
        {
            RemoveListener(evt, (Delegate)callback);
        }
        public void RemoveListener(string evt, Action callback)
        {
            RemoveListener(evt, (Delegate)callback);
        }
        private void RemoveListener(string evt, Delegate callback)
        {
            Delegate listener;
            if (_listeners.TryGetValue(evt, out listener))
            {
                listener = Delegate.Remove(listener, callback);
                if (listener == null)
                {
                    _listeners.Remove(evt);
                }
                else
                {
                    _listeners[evt] = listener;
                }
            }
        }

        public void Dispatch<T1, T2, T3, T4>(string evt, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
        {
            Delegate[] methods = GetMethods(evt);
            if (methods != null)
            {
                foreach (Delegate m in methods)
                {
                    try
                    {
                        ((Action<T1, T2, T3, T4>)m)(arg1, arg2, arg3, arg4);
                    }
                    catch (Exception e) { LogError(e); }
                }
            }
        }

        public void Dispatch<T1, T2, T3>(string evt, T1 arg1, T2 arg2, T3 arg3)
        {
            Delegate[] methods = GetMethods(evt);
            if (methods != null)
            {
                foreach (Delegate m in methods)
                {
                    try
                    {
                        ((Action<T1, T2, T3>)m)(arg1, arg2, arg3);
                    }
                    catch (Exception e) { LogError(e); }
                }
            }
        }

        public void Dispatch<T1, T2>(string evt, T1 arg1, T2 arg2)
        {
            Delegate[] methods = GetMethods(evt);
            if (methods != null)
            {
                foreach (Delegate m in methods)
                {
                    try
                    {
                        ((Action<T1, T2>)m)(arg1, arg2);
                    }
                    catch (Exception e) { LogError(e); }
                }
            }
        }

        public void Dispatch<T>(string evt, T arg)
        {
            Delegate[] methods = GetMethods(evt);
            if (methods != null)
            {
                foreach (Delegate m in methods)
                {
                    try
                    {
                        ((Action<T>)m)(arg);
                    }
                    catch (Exception e) { LogError(e); }
                }
            }
        }

        public void Dispatch(string evt)
        {
            Delegate[] methods = GetMethods(evt);
            if (methods != null)
            {
                foreach (Delegate m in methods)
                {
                    try
                    {
                        ((Action)m)();
                    }
                    catch (Exception e) { LogError(e); }
                }
            }
        }

        private Delegate[] GetMethods(string evt)
        {
            Delegate listener;
            if (_listeners.TryGetValue(evt, out listener))
            {
                return listener.GetInvocationList();
            }
            return null;
        }

        private static void LogError(Exception e)
        {
            UnityEngine.Debug.LogError(e);
        }
    }
  • 相关阅读:
    C# 通过反射初探ORM框架的实现原理
    Redis-Nosql数据库入门
    HTTPS 建立连接的详细过程
    Spring面试题
    struts2面试整理
    Java面试基本知识
    Spring MVC面试整理
    Mybatis面试整理
    Sublime 正则替换
    Hiberante知识点梳理
  • 原文地址:https://www.cnblogs.com/sanyejun/p/7930254.html
Copyright © 2011-2022 走看看