<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                在Unity中我們經常會用到對象池,使用對象池無非就是解決兩個問題: * 一是減少 new 時候尋址造成的消耗,該消耗的原因是內存碎片。 * 二是減少 Object.Instantiate 時內部進行序列化和反序列化而造成的CPU消耗。 想進一步了解對象池模式優化原理的同學可以參閱: [對象池模式:http://gpp.tkchu.me/object-pool.html](http://gpp.tkchu.me/object-pool.html),本篇主要講如何實現一個精簡并且靈活的對象池。 ## 設計: 首先我們要弄清楚本篇對象池的幾個概念,否則直接上代碼大家會一頭霧水。 從字面上理解對象池,池的意思就是容器。我們可以從池中獲取一個對象(一條魚),也可以向池中放入一個對象(一條魚)。獲取的操作我們叫Allocate(分配),而放入一個對象我們叫Recycle(回收)(ps:也有很多習慣叫Spawn 和 Despawn 的,這個看自己習慣了)。所以我們可以定義池的接口為如下: ```cs public interface IPool<T> { T Allocate(); bool Recycle(T obj); } ``` 為什么要用泛型呢?因為筆者開頭說過,本篇主要講如何實現一個精簡并且靈活的對象池。這個靈活很大一部分是通過泛型體現的。 前面有說過,池是容器的意思,在C#中可以是List,Queue或者Stack甚至是數組。所以對象池本身要維護一個容器。本篇我們選取Stack來作為池容器,原因是當我們在Allocate和Recycle時并不關心緩存的存儲的順序,只要求緩存對象的地址是連續的。代碼如下所示: ```cs using System.Collections.Generic; public abstract class Pool<T> : IPool<T> { ... protected Stack<T> mCacheStack = new Stack<T>(); ... } ``` Pool是個抽象類,為什么呢? 因為筆者開頭說過,本篇主要講如何實現一個精簡并且靈活的對象池。這個靈活很大一部分是通過抽象類體現的。 現在對象的存取和緩存接口都設計好了,那么這些對象是從哪里來的呢?我們分析下,創建對象我們知道有兩種方式,反射構造方法和new一個對象。對象池的一個重要功能就是緩存,要想實現緩存就要求對象可以在對象池內部進行創建。所以我們要抽象出一個對象的工廠,代碼如下所示: ```cs public interface IObjectFactory<T> { T Create(); } ``` 那么大家要問為什么要用工廠? 因為筆者開頭說過,本篇主要講如何實現一個精簡并且靈活的對象池。這個靈活很大一部分是通過工廠體現的。 OK,現在對象的創建,存取,緩存的接口都設計好了。下面放出Pool的全部代碼。 ```cs using System.Collections.Generic; public abstract class Pool<T> : IPool<T> { #region ICountObserverable /// <summary> /// Gets the current count. /// </summary> /// <value>The current count.</value> public int CurCount { get { return mCacheStack.Count; } } #endregion protected IObjectFactory<T> mFactory; protected Stack<T> mCacheStack = new Stack<T>(); /// <summary> /// default is 5 /// </summary> protected int mMaxCount = 5; public virtual T Allocate() { return mCacheStack.Count == 0 ? mFactory.Create() : mCacheStack.Pop(); } public abstract bool Recycle(T obj); } ``` 代碼不多,設計階段基本就這樣。下面介紹如何實現一個簡易的對象池。 ## 對象池實現 首先要實現一個對象的創建器,代碼如下所示: ```cs using System; public class CustomObjectFactory<T> : IObjectFactory<T> { public CustomObjectFactory(Func<T> factoryMethod) { mFactoryMethod = factoryMethod; } protected Func<T> mFactoryMethod; public T Create() { return mFactoryMethod(); } } ``` 比較簡單,只是維護了一個返回值為T的委托(如果說得有誤請指正)。 對象池實現: ```cs using System; /// <summary> /// unsafe but fast /// </summary> /// <typeparam name="T"></typeparam> public class SimpleObjectPool<T> : Pool<T> { readonly Action<T> mResetMethod; public SimpleObjectPool(Func<T> factoryMethod, Action<T> resetMethod = null,int initCount = 0) { mFactory = new CustomObjectFactory<T>(factoryMethod); mResetMethod = resetMethod; for (int i = 0; i < initCount; i++) { mCacheStack.Push(mFactory.Create()); } } public override bool Recycle(T obj) { mResetMethod.InvokeGracefully(obj); mCacheStack.Push(obj); return true; } } ``` 實現也很簡單,這里不多說了。 ## 如何使用? ```cs var fishPool = new SimpleObjectPool<Fish>(() => new Fish(), null, 100); Log.I("fishPool.CurCount:{0}", fishPool.CurCount); var fishOne = fishPool.Allocate(); Log.I("fishPool.CurCount:{0}", fishPool.CurCount); fishPool.Recycle(fishOne); Log.I("fishPool.CurCount:{0}", fishPool.CurCount); for (int i = 0; i < 10; i++) { fishPool.Allocate(); } Log.I("fishPool.CurCount:{0}", fishPool.CurCount); ``` 運行結果: ```cs fishPool.CurCount:100 fishPool.CurCount:99 fishPool.CurCount:100 fishPool.CurCount:90 ``` OK,本篇就介紹到這里 轉載請注明地址:涼鞋的筆記:[liangxiegame.com](http://liangxiegame.com) ## 更多內容 * QFramework 地址:[https://github.com/liangxiegame/QFramework](https://github.com/liangxiegame/QFramework) * QQ 交流群:[623597263](http://shang.qq.com/wpa/qunwpa?idkey=706b8eef0fff3fe4be9ce27c8702ad7d8cc1bceabe3b7c0430ec9559b3a9ce66) * **Unity 進階小班**: * 主要訓練內容: * 框架搭建訓練(第一年) * 跟著案例學 Shader(第一年) * 副業的孵化(第二年、第三年) * 權益、授課形式等具體詳情請查看[《小班產品手冊》](https://liangxiegame.com/master/intro):https://liangxiegame.com/master/intro * 關注公眾號:liangxiegame 獲取第一時間更新通知及更多的免費內容。 ![](http://file.liangxiegame.com/38eccb55-40b2-4845-93d6-f5fb50ff9492.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看