有些事情一帧之内只需要做一次,比如收发邮件时,一帧内数据层多次的变化,表现层只需要一次更新。
我采用协程做这个事情,为了避免发起多个协程,我记录了一个协程是否发起的变量。
但是u3d里的coroutine,在发起的脚本acvited=false后,就不更新了,并且我测试过,再恢复成actived =
true,协程依旧不更新了,就像没调用一样。
而我那些标志还是【已经发起】状态,这样就发生死锁了----想更新的发起不了,之前的异常结束导致标志复位不了。
上述现象发生在用户收到邮件后的一帧里操作了鼠标关闭了邮件系统。
由于网络消息分派比用户输入的时机靠前(我们项目里的既有结构),导致协程发起了,但实际无法执行。
如果先关闭,再处理数据,就会走关闭时的处理,就不会出错了---可是网络消息也是有可能导致UI关闭的,看业务逻辑了。
回到现状,
我只能在隐藏的时候,恢复标志。
可是u3d隐藏对象过于随意,大多使用GameObject.SetActiveRecursively(bool)接口干活。
这导致我无法保证所有处理该对象的代码都知道恢复标志这个事情。
我可以提炼一个特殊的Visible接口,确保标志恢复,但是会有以下情况:
如果将逻辑分散到多个脚本组件,如何访问到这个特殊的Visible接口就会变得很麻烦。
如果这样,那我还不如用Update来做。
目前的解决方案是:
一个场合恰好只有一个脚本,能满足“提炼一个特殊的Visible接口,确保标志恢复”。
另外一个场合是很多脚本,刚好协程只做可见性控制,这导致出错了也不怕,因为会被其他可见性操作恢复。
谁能给出基于Coroutine的不会出死锁问题的更新方案?
今天在好友列表的更新也用了协程。而且关闭逻辑刚好在别的脚本里,现在的打算是让关闭按钮捕获用户输入后,转给Model层,再分别通知各个脚本组件执行恢复操作。
希望这么做了,效率会比update效率高,反正我觉得这不是核心性能瓶颈。