【Lua】Timer定时器或Coroutine协程无法完整执行结束

定时器或协程无法正常执行完成

原因:

被提前销毁定时器或协程

①正常被自身逻辑提前销毁,正常排查解决bug即可。(废话)

*② 被其它销毁,定时器和协程对象均为对象池对象,外部可能一直持有某个已标记回收的对象,导致你获取到的是一个被其他持有的定时器。

定时器可能在被不知情情况下被销毁掉,导致无法正常执行完成定时器回调。

最稳妥处理:

封装一个中介对象处理定时器业务,外界不直接调用对象池对象,而是调用中介者来执行定时器操作;

中介者函数,调用前均需检查定时器对象是否为空(null)值,若空值则不执行并警告提示,否则正常。

中介者对象负责创建、管理、销毁定时器,以及最重要的保证定时器它自身结束时进行置空定时器对象;

具体:定时器创建,中介持有定时器对象,初始化定时器传入回调方法,在回调方法里置空定时器引用。

(注意:并不一定是定时器这种有明确回调的对象池对象,而是所有可能被外界持有的对象池对象均需要中介来保证统一使用正常逻辑调用,而且是必须要使用中介统一操作,不然依旧会有问题)

根本保证处理:

其实归根结底是外界无法感知到这对象已回收了,自己还持有者一个已回收的对象(但又被其他人从对象池重新取出的对象),那么我用一个全局唯一单例字典<int,对象池对象类型>即可解决。

在每次创建对象池对象时,设置一个唯一ID,ID自增+1,并将ID和自身存入全局唯一字典,创建对象池对象后返回给外界的不能是一个对象,而是一个ID,外界通过ID来获取对象调用函数,

如果出现了问题顶多就只是报空,如果你有做中介 可以每次调用函数时判空,为空则警告即可。

最难受处理:

检查所有持有对象池对象,在它自身被销毁时,外界需感知到并置空对象。(只能一点点排查)

一切原因都是因为你用了对象池!对象池就肯定会有这种持有已回收对象的问题,所以频繁使用对象池的要注意了,这种问题一旦发生,几乎是不会报错的,你只能一个个点排查或按照我说的采用中介模式保证你调用的对象池对象是正确的,是没有被其他人引用的,是已经不在池子里的!

相关推荐
小师兄吃牛肉4 天前
C++ 与 Lua 的协程交互:从原理到实战
c++·lua·交互
喜欢的名字被抢了4 天前
09-Redis 进阶原理篇:单线程、多线程、过期、LRU-LFU、Fork 与 Lua
数据库·redis·lua
白山编程大哥4 天前
Lua 中使用 C 语言的用户自定义类型——userdata
c语言·junit·lua
大侠归来7 天前
C++ 与 Lua 的协程交互:从原理到实战
c++·lua·交互
疯狂成瘾者7 天前
海康 Artemis 接口对接
开发语言·lua
一线灵7 天前
跨平台游戏引擎 Axmol-2.11.5 发布
游戏引擎·lua
鑫鑫哥adam8 天前
一个 1x1 贴图,是怎么炸掉整个热更包的?
unity3d·游戏开发
Behavior8 天前
Unity 手游动态更换 App 图标 — Android 与 iOS 双端技术方案
c#·unity3d·游戏开发
SmalBox9 天前
03-03-架构篇-Runtime加载系统架构
unity3d·游戏开发
SmalBox9 天前
03-02-架构篇-Editor打包系统架构
unity3d·游戏开发