Unity的dubbo 序列化问题配表问题用什么方法比较好

2197人阅读
Unity3d(21)
这段时间在研究和学习C#的序列化和反序列化的东西。发现这是一个非常友好的数据本地store的方式。但是在使用过程中也有很多有意思的地方,我这里把我越到的问题列一下。我使用的是C#的二进制形式的序列化和反序列化。
参考了,还有。这两个参考地方都有对于的code。从code中可以得到的结果是:在serialize之前,都是将需要序列化的数据放到一个结构体里面去,然后开始序列化。对于这个被序列化的结构体的要求就是她已经实现了ISerializable的GetObjectData方法,还有一个参数为SerializationInfo
info, StreamingContext context的构造函数。在这个构造函数中将从info中得到的信息赋值给这个数据结构的属性变量。而在GetObjectData方法中有着与以上说的构造函数一直的参数,在这个函数中是将数据结构的属性变量的指添加到info中去。如:
[Serializable]
public class MyObject : ISerializable
public int n1;
public int n2;
public MyObject()
protected MyObject(SerializationInfo info, StreamingContext context)
n1 = info.GetInt32(&i&);
n2 = info.GetInt32(&j&);
str = info.GetString(&k&);
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
info.AddValue(&i&, n1);
info.AddValue(&j&, n2);
info.AddValue(&k&, str);
回到开始之处,如何开始序列化。看code:
using System.IO;
using System.C
using System.Runtime.Serialization.Formatters.B
using System.Runtime.S
public class App
[STAThread]
static void Main()
Serialize();
Deserialize();
static void Serialize()
// Create a hashtable of values that will eventually be serialized.
Hashtable addresses = new Hashtable();
addresses.Add(&Jeff&, &123 Main Street, Redmond, WA 98052&);
addresses.Add(&Fred&, &987 Pine Road, Phila., PA 19116&);
addresses.Add(&Mary&, &PO Box 112233, Palo Alto, CA 94301&);
// To serialize the hashtable and its key/value pairs,
// you must first open a stream for writing.
// In this case, use a file stream.
FileStream fs = new FileStream(&DataFile.dat&, FileMode.Create);
// Construct a BinaryFormatter and use it to serialize the data to the stream.
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, addresses);
catch (SerializationException e)
Debug.Log(&Failed to serialize. Reason: & + e.Message);
fs.Close();
static void Deserialize()
// Declare the hashtable reference.
Hashtable addresses
// Open the file containing the data that you want to deserialize.
FileStream fs = new FileStream(&DataFile.dat&, FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
// Deserialize the hashtable from the file and
// assign the reference to the local variable.
addresses = (Hashtable) formatter.Deserialize(fs);
catch (SerializationException e)
Debug.Log(&Failed to deserialize. Reason: & + e.Message);
fs.Close();
// To prove that the table deserialized correctly,
// display the key/value pairs.
foreach (DictionaryEntry de in addresses)
Debug.Log( de.Key+ de.Value);
需要注意的是,什么的做法在mac上是ok的。但是,如果发布到ios上面的话,可能就出错了哦。上面使用的是hashtable,如果她的key或value是自定义的一种类型的话,在ios中可能就,filename unknown 0 等等的。。。我在网上找到的方式是不使用自定义的类型,而是将自定义的数据里面的数据字段重新组合成基本数据类型再作为value后进行序列化。比如: 一个自定义数据类型由三种自定义类型构成,int m_n ,bool m_b,string m_str。我将按照这样的方式来组合成一个新的string,
string value = new StringBuilder().Append(m_n).Append(“#”).Append(m_b).Append(“#”).Append(m_str).ToString();这样就得到了一个key对应的value。在反序列化的时候,使用split函数可以将这个string再拆开成int,bool,string类型。这样数据就还原了。如此之后也可以解决在ios上面的filename unknown 0的问题。&
原方地址:
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
(5)(2)(1)(1)(3)(1)(1)(1)(2)(1)(2)(8)(1)(1)(2)(1)(1)(3)关注游戏葡萄
微信扫描二维码关注
游戏葡萄公众号
的其他文章
的其他文章
的其他文章
TalkingData
的其他文章
的其他文章
的其他文章
的其他文章
的其他文章
的其他文章
All Rights Reserved
赞助Sponsor
赞助Sponsor
阅读Articles
数据库Data
数据库Data
招聘Recruitment
联系我们Contact
友情链接Links
游戏葡萄订阅号Unity序列化高级篇及应用篇
如果你想把自定义的对象显示在Inspector。
如果你想给自定义的对象在Inspector面板上赋值。
如果你想自定义资产对象并且拖拽给自定义的对象。
如果你想系统的学习Unity提供的序列化。
如果你想从csv中读取数据。
如果你想创建自定义资产。
如果你想通过代码加载自定义资产。
如果你想把自定义资产进行打包成AssetBundle。
如果你想加载打成AssetBundle的自定义资产。
那么这个课程你一定不要错过,本教程为Unity序列化的高级篇及应用篇,学习如何把自定义的对象显示在Inspector,如何给自定义的对象在Inspector面板上赋值,如何自定义资产对象并且拖拽给自定义对象,使用Unity提供的序列化读取策划
数据等内容。
课程目录:
课时1:Unity序列化高级篇及应用篇(1)&
课时2:Unity序列化高级篇及应用篇(2)&
课时3:Unity序列化高级篇及应用篇(3)&
课时4:Unity序列化高级篇及应用篇(4)
课程学习地址:/course/128
我学院在线教育平台内容覆盖了Unity、3Dsmax、Maya、Photoshop、Cocos等所有主流应用软件和插件工具,涵盖3D动画、模型、材质、渲染、特效、影视后期及2D概念设计、插画、漫画等所有创作主题,囊括了当今互联网游戏中所有的动漫设计、原画创作内容,如三维动画、影视特效、游戏制作、原画设计、产品原型设计等内容。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。4877人阅读
unity(34)
1. Resource.UnloadAsset()清理引用资源&和destroy()清理实例化资源&
2.Load出来的Assets其实就是个数据源,用于生成新对象或者被引用,生成的过程可能是复制(clone)也可能是引用(指针)
当你Destroy一个实例时,只是释放那些Clone对象,并不会释放引用对象和Clone的数据源对象,Destroy并不知道是否还有别的object在引用那些对象。
等到没有任何 游戏场景物体在用这些Assets以后,这些assets就成了没有引用的游离数据块了,是UnusedAssets了,这时候就可以通过&Resources.UnloadUnusedAssets来释放,Destroy不能完成这个任
务,AssetBundle.Unload(false)也不行,AssetBundle.Unload(true)可以但不安全,除非你很清楚没有任何 对象在用这些Assets了。
配个图加深理解:
--------------------------------------------------------------------------------
关于客户端读表有多种方式
1.最简单的就是xml表的读取,可以使用c#的库来读,也可以使用官方推荐的一个xml解析包来读,官方推荐当然更好,因为包含的库比较少,而且也高效,c#的xml读取会增加几m的包大小。
2.使用csv读取。这种格式存成txt格式,方便用excel编辑。相比xml来说,该方法更好,因为不需要额外的包来解析xml,只需要读取tet来解析成对应数据就行。解析自己写,很简单。但是大量text的读取
字符串解析,也会造成内存过去,和效率表现一般。
3. 使用序列化方法读取:该方法比上面2种方法 效率都高,内存占用都少,但是用法稍微复杂点。但是对于MMO的话 也许这个是较好的选择方式。用法:根据表的内容来定义序列化的结构体参数,也就是说代码定义好的key从表去读。把所有数据都存到一个prefab中。最后打包使用的是prefab的数据。就不需要解析表了。也可以存成byte文件。
该方法效率很高,内存占得也少。缺点是使用不方便,策划每加一张表,都需要程序来定义结构体。而且在后边更新表的时候,也需要重新制作prefab来更新数据。
---------------------------------------------------------
关于unity官方的内存:
1. 首先有个总内存叫Totalresercerdmemory,其次有个allocate内存,这个是游戏运行使用内存,再次有个unusedreserverdmemory,该内存是未使用的临时内存。Totalresercerdmemory=allocate+unusedreserverdmemory;一般情况下unusedreserverdmemory最好是只占总内存的很小的百分比会比较好。
但是部分算法
会极大的消耗unusedreserverdmemory内存。1 频繁的字符串连接和解析。2 频繁的调用可以返回list类型函数,像读取xml表就需要经常返回很大的table数据,这个会极大消耗总内存。这也是为什么客户端读表用序列化更好。
频繁字符型解析推荐使用stringbuilder。频繁的临时变量或者list生成,建议定义一个全局的list 每次都用该list来计算 然后返回。这样就不会创建很多临时内存。千万不要在函数内new一个list返回出来,虽然看起来还行,但是频繁调用很消耗内存。
其他的内存优化包括图集整理,及时释放,和对象池的使用。如果场景切换的时候 要加载大量数据的时候,可能会使临时内存增加,建议切换场景先切换到空场景,进行内存释放,释放完后再切换到目标场景。
4.System.GC.Collect(0,System.GCColletionMode.Optimized)
可以在update里边 适当时间调用这个,根据情况来释放内存。
System.GC.Collect(0,System.GCColletionMode.Forced)
在切换场景的时候 强制释放内存。
还可以在切换场景的时候调用System.GC.RemoveMemoryPressure(byte)和System.GC.AddMemoryPressure(byte),来告诉gc有多余内存需要释放,也可以在通用的读表的地方
调用,读完就释放。
关于用Profiler监控内存问题:Profiler.GetTotalReserverdMemory()=Profiler.GetTotalunusedReserverdMemory()+Profiler.GetTotalAllocatedMemory()
总内存=垃圾(临时)内存+实际分配内存,程序占得内存为总内存。该数据在PC上可以实时监测到内存大小,比如我们游戏是300=120+180这个水平。但是在Android设备上消耗总内存也是300M左右,但是输出的结果为110=5+100左右,和实际内存相差很大。根据我们推断,在pc上unity是完全自己管理内存,所以他知道所有内存池的分配。但是在Android上可能系统底层本身对应用分配了一个内存池,unity也有一个内存池,但是属于系统池内。unity只管理自己的内存,Android底层内存他管理不到,所以数据也不一样。Android想要获取实际内存
可能还是需要去系统获取。系统和unity内存池都有一个冗余部分。
1.切换场景释放资源和GC
2.内存总量减少,压缩分类图集。
3.碎片化减少,少用string的分割和连接,少在临时函数里new
4.配置表采用序列化的方式。
5.在合适的时候释放资源,比如当ui打开过多,或者隔一段时间,或者在某时刻内存过大。但是释放内存肯定会卡顿一下,所以时机要选好,比如boss开始动画,结束动画
,在切换ui可以load一会儿的地方。为避免战斗卡顿,一定不能在战斗里边随意释放。
6.内存只能尽量减少,尽量避免碎片化,不可能完全避免。
----------
文件的读写xml
csv 序列化,csv自己解析 比较好 但是大量数据内存大 效率不好。最好的是序列化。序列化有2种方式:1.是保存成prefab模式,直观 好看 参考fbd.cs。2.是保存成byte文件:效率更高。因为unity的prefab序列化过程可能还需要申请临时内存 保存临时数据。不过我觉得差不多吧。
[Serializable]
public class People
& & public string Name { }
& & public int Age { }
}//prefab 模式就是在mono里定义public的 People对象,把数据写进去,存成prefab。unity编辑器方便的查看修改序列化内容。
void Write(){//序列化写byte文件
FileStream fs = new FileStream(&Asset\test.byte&, FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
List&People& ps = new List&People&();//也可以只new 一个对象
ps.Add(new People() { Name = &gg&, Age = 24 });
ps.Add(new People() { Name = &yy&, Age = 23 });
bf.Serialize(fs, ps);
fs.Close();
void Read(){//读byte文件
FileStream fs = new FileStream(&Asset\test.byte&, FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
List&People& ps = bf.Deserialize(fs) as List&People&;
debug.log(ps[0].name)
///ustcwhc/archive//2232195.html
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:66669次
积分:1058
积分:1058
排名:千里之外
原创:39篇
(1)(3)(2)(2)(1)(1)(1)(1)(1)(1)(3)(3)(2)(2)(3)(2)(1)(2)(1)(1)(1)(2)(5)}

我要回帖

更多关于 dubbo 序列化 配置 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信