{"id":5625,"date":"2024-03-31T09:38:31","date_gmt":"2024-03-31T01:38:31","guid":{"rendered":"http:\/\/blog.coolcoding.cn\/?p=5625"},"modified":"2024-03-31T09:47:50","modified_gmt":"2024-03-31T01:47:50","slug":"%e8%a7%a3%e5%86%b3unityxlua%e7%9a%84%e4%b8%80%e4%ba%9b%e5%86%85%e5%ad%98%e9%97%ae%e9%a2%98","status":"publish","type":"post","link":"https:\/\/blog.coolcoding.cn\/?p=5625","title":{"rendered":"\u89e3\u51b3Unity+XLua\u5185\u5b58\u7684\u4e00\u4e9b\u8bb0\u5f55"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">\u4e00\u3001\u8ddf\u8e2a\u5bf9\u8c61\u5f15\u7528<\/h2>\n\n\n\n<p>Lua\u4e2d\u7684\u5bf9\u8c61\u88ab\u6301\u6709\uff08\u5f15\u7528\uff09\uff0c\u4f1a\u5bfc\u81f4\u8d44\u6e90\u7684\u5f15\u7528\u4e5f\u65e0\u6cd5\u65ad\u5f00\uff0c\u6240\u4ee5\u9700\u8981\u8ffd\u8e2alua\u4e2d\u5bf9\u8c61\u662f\u5426\u5b58\u5728\u3002<\/p>\n\n\n\n<p>\u4f7f\u7528lua\u7684weak\u8868\uff0c\u628a\u9700\u8981\u8ffd\u8e2a\u7684\u5bf9\u8c61\u653e\u5728weak\u8868\u4e2d\uff0c\u5728\u6307\u5b9a\u7684\u65f6\u5019\u68c0\u67e5\u6b64\u8868\u4e2d\u662f\u5426\u5b58\u5728\u5bf9\u8c61\uff0c\u82e5\u672a\u88ab\u56de\u6536\uff0c\u5219\u8bf4\u660e\u51fa\u73b0\u4e86\u6cc4\u6f0f\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>local _MV = { __mode = \"v\" }\n\n---@class WeakObjMgr\nlocal _M = {}\n_M.__index = _M\n\n---@param obj table|function \u8981\u8ffd\u8e2a\u7684\u5bf9\u8c61\n---@param typeName string \u5927\u7c7b\u540d\u79f0\n---@param objName string \u5c0f\u7c7b\u540d\u79f0\nfunction _M:Add(typeName, objName, obj)\n    local objType = type(obj)\n    if objType ~= \"function\" and objType ~= \"table\" then\n        return false\n    end\n    local pool = self.list&#91;typeName]\n    if pool == nil then\n        pool = {}\n        self.list&#91;typeName] = pool\n    end\n    table.insert(pool, setmetatable({ objName, obj }, _MV))\n    return true\nend\n\n--- \u6c47\u62a5\nfunction _M:Report()\n    collectgarbage(\"collect\")\n    local tips = {}\n    for typeName, pool in pairs(self.list) do\n        local len = #pool\n        for i = len, 1, -1 do\n            if pool&#91;i]&#91;2] == nil then\n                table.remove(pool, i)\n            else\n                table.insert(tips, typeName .. \":\" .. tostring(pool&#91;i]&#91;1]))\n            end\n        end\n    end\n    return table.concat(tips, \"\\n\")\nend\n\n---@type WeakObjMgr\nWeakObjMgrIns = setmetatable({ list = {} }, _M)\n\n--- \u4f7f\u7528\u7684\u65f6\u5019WeakObjMgrIns:Add(\"mainCity\", \"avatar\", avatarObj)<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e8c\u3001\u5728XLua\u4e2d\u6dfb\u52a0\u65b0\u589euserdata\u7684\u8ffd\u8e2a<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>public partial class ObjectPool\r\n{\r\n    public int GetCount()\r\n    {\r\n        int c = 0;\r\n        for(int i=0; i&lt;list.Length; ++i)\r\n        {\r\n            if (list&#91;i].obj != null)\r\n            {\r\n                ++c;\r\n            }\r\n        }\r\n        return c;\r\n    }\r\n\r\n    private HashSet&lt;int> mSaveSnap = new HashSet&lt;int>();\r\n    public void SaveSnap()\r\n    {\r\n        for(int i=0; i&lt;list.Length; ++i)\r\n        {\r\n            var obj = list&#91;i].obj;\r\n            if (obj != null)\r\n            {\r\n                mSaveSnap.Add(obj.GetHashCode());\r\n            }\r\n        }\r\n    }\r\n\r\n    private static string GetObjName(object obj)\r\n    {\r\n        try\r\n        {\r\n            if (obj is UnityEngine.GameObject)\r\n            {\r\n                return (obj as UnityEngine.GameObject).name;\r\n            }\r\n\r            ...\u5176\u5b83\u7684\u4e00\u4e9b\u5bf9\u8c61\u540d\u79f0\n        }\r\n        catch(Exception)\r\n        {\r\n        }\r\n        return string.Empty;\r\n    }\r\n\r\n    \/\/ \u5bf9\u6bd4\u51fa\u589e\u91cf\n    public string Compare()\r\n    {\r\n        HashSet&lt;int> current = new HashSet&lt;int>();\r\n\r\n        for(int i=0; i&lt;list.Length; ++i)\r\n        {\r\n            var obj = list&#91;i].obj;\r\n            if (obj != null)\r\n            {\r\n                current.Add(obj.GetHashCode());\r\n            }\r\n        }\r\n\r\n        List&lt;(string typeName, string objName, int n)> ls = new List&lt;(string typeName, string objName, int)>();\r\n        foreach(var id in current)\r\n        {\r\n            if (mSaveSnap.Contains(id))\r\n            {\r\n                continue;\r\n            }\r\n\r\n            if (ObjectPool.mAllObjs.TryGetValue(id, out var info))\r\n            {\r\n                ls.Add((info.tyepName, info.objName, 1));\r\n            }\r\n        }\r\n\r\n        ls.Sort( (a,b)=>\r\n        {\r\n            if (a.typeName == b.typeName)\r\n            {\r\n                return a.objName.CompareTo(b.objName);\r\n            }\r\n            return a.typeName.CompareTo(b.typeName);\r\n        });\r\n\r\n        int count = ls.Count;\r\n        for(int i=count-1; i>0; --i)\r\n        {\r\n            if (ls&#91;i].typeName == ls&#91;i-1].typeName &amp;&amp; ls&#91;i].objName == ls&#91;i-1].objName)\r\n            {\r\n                ls.RemoveAt(i);\r\n                ls&#91;i-1] = (ls&#91;i-1].typeName, ls&#91;i-1].objName, ls&#91;i-1].n+1);\r\n            }\r\n        }\r\n\r\n        StringBuilder sb = new StringBuilder();\r\n\r\n        foreach(var s in ls)\r\n        {\r\n            if (s.n > 1)\r\n                sb.AppendLine($\"{s.typeName} &#91;{s.n}] : {s.objName}\");\r\n            else\r\n                sb.AppendLine($\"{s.typeName} : {s.objName}\");\r\n        }\r\n        return sb.ToString();\r\n    }\r\n    \r\n    public static Dictionary&lt;int, (string tyepName, string objName)> mAllObjs = new Dictionary&lt;int, (string, string)>();\r\n    \r\n    public void PostAdd(object obj)\r\n    {\r\n        if (obj == null)\r\n        {\r\n            return;\r\n        }\r\n    \r\n        var typeName = obj.GetType().Name;\r\n        var objName = GetObjName(obj);\r\n        var hashCode = obj.GetHashCode();\r\n        mAllObjs&#91;hashCode] = (typeName, objName);\r\n    }\r\n}<\/code><\/pre>\n\n\n\n<p>\u7136\u540e\u5b9a\u65f6\u8fdb\u884cCompare<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e09\u3001XLua\u9001\u7684LuaMemoryLeakChecker<\/h2>\n\n\n\n<p>\u4e0d\u592a\u597d\u7528\uff0c\u8f93\u51fa\u51fa\u6765\u7684\u5bf9\u8c61\u6bd4\u8f83\u6df7\u4e71<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>\u672a\u5b8c\u5f85\u7eed<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4e00\u3001\u8ddf\u8e2a\u5bf9\u8c61\u5f15\u7528 Lua\u4e2d\u7684\u5bf9\u8c61\u88ab\u6301\u6709\uff08\u5f15\u7528\uff09\uff0c\u4f1a\u5bfc\u81f4\u8d44\u6e90\u7684\u5f15\u7528\u4e5f\u65e0\u6cd5\u65ad\u5f00\uff0c\u6240\u4ee5\u9700\u8981\u8ffd\u8e2alua\u4e2d\u5bf9\u8c61\u662f\u5426\u5b58\u5728\u3002 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/5625"}],"collection":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5625"}],"version-history":[{"count":3,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/5625\/revisions"}],"predecessor-version":[{"id":5628,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/5625\/revisions\/5628"}],"wp:attachment":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5625"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5625"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5625"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}