版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/iceSony/article/details/83039196
本文由@唐三十胖子出品,转载请注明出处。
文章链接:https://blog.csdn.net/iceSony/article/details/83039196
协程的创建常见问题:
yield return 0;错
yield return null;对
yield return new WaitForSeconds(1f);错
WaitForSeconds delay = new WaiForSeconds(1f);
yield return delay;对
实际中写一个全局的
代码如下:
using System.Collections.Generic; using UnityEngine; using UnityEngine.Assertions.Comparers; // Usage: // yield return new WaitForEndOfFrame(); => yield return Yielders.EndOfFrame; // yield return new WaitForFixedUpdate(); => yield return Yielders.FixedUpdate; // yield return new WaitForSeconds(1.0f); => yield return Yielders.GetWaitForSeconds(1.0f); // http://forum.unity3d.com/threads/c-coroutine-waitforseconds-garbage-collection-tip.224878/ public static class Yielders { public static bool Enabled = true; public static int _internalCounter = 0; // counts how many times the app yields // #gulu WARNING: // Code commented below are incorrect in Unity 5.5.0 // - float DOES NOT needs customized IEqualityComparer (but enums and structs do) // however all these lines are kept to help later reader to share this knowledge //------------------------------------------------------------------ ///////////////////// obsoleted code begins \\\\\\\\\\\\\\\\\\\\\\\\ //// dictionary with a key of ValueType will box the value to perform comparison / hash code calculation while scanning the hashtable. //// here we implement IEqualityComparer<float> and pass it to your dictionary to avoid that GC //class FloatComparer : IEqualityComparer<float> //{ // bool IEqualityComparer<float>.Equals(float x, float y) // { // return x == y; // } // int IEqualityComparer<float>.GetHashCode(float obj) // { // return obj.GetHashCode(); // } //} //\\\\\\\\\\\\\\\\\\\\\\\\ obsoleted code ends ///////////////////// //------------------------------------------------------------------ static WaitForEndOfFrame _endOfFrame = new WaitForEndOfFrame(); public static WaitForEndOfFrame EndOfFrame { get { _internalCounter++; return Enabled ? _endOfFrame : new WaitForEndOfFrame(); } } static WaitForFixedUpdate _fixedUpdate = new WaitForFixedUpdate(); public static WaitForFixedUpdate FixedUpdate { get { _internalCounter++; return Enabled ? _fixedUpdate : new WaitForFixedUpdate(); } } public static WaitForSeconds GetWaitForSeconds(float seconds) { _internalCounter++; if (!Enabled) return new WaitForSeconds(seconds); WaitForSeconds wfs; if (!_waitForSecondsYielders.TryGetValue(seconds, out wfs)) _waitForSecondsYielders.Add(seconds, wfs = new WaitForSeconds(seconds)); return wfs; } public static void ClearWaitForSeconds() { _waitForSecondsYielders.Clear(); } static Dictionary<float, WaitForSeconds> _waitForSecondsYielders = new Dictionary<float, WaitForSeconds>(100, new FloatComparer()); }
重构代码来减小GC的影响
即使我们减小了代码在堆内存上的分配操作,代码也会增加GC的工作量。最常见的增加GC工作量的方式是让其检查它不必检查的对象。struct是值类型的变量,但是如果struct中包含有引用类型的变量,那么GC就必须检测整个struct。如果这样的操作很多,那么GC的工作量就大大增加。在下面的例子中struct包含一个string,那么整个struct都必须在GC中被检查:
public struct ItemData { public string name; public int cost; public Vector3 position; } private ItemData[] itemData;
我们可以将该struct拆分为多个数组的形式,从而减小GC的工作量:
private string[] itemNames; private int[] itemCosts; private Vector3[] itemPositions;
同理适用于Class