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

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

原因:

被提前销毁定时器或协程

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

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

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

最稳妥处理:

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

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

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

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

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

根本保证处理:

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

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

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

最难受处理:

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

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

相关推荐
SmalBox7 小时前
02-07-原理篇-文件系统与跨平台适配
unity3d·游戏开发
SmalBox2 天前
02-06-原理篇-热更新与版本管理
unity3d·游戏开发
liulilittle2 天前
麻将结算全链路语义(SETTLE_SEMANTICS)
ai·自动化·llm·mock·lua·测试
SmalBox2 天前
02-05-原理篇-资源加载与缓存机制
unity3d·游戏开发
liulilittle2 天前
麻将服务器崩溃补偿与异常处理语义(CRASH_SEMANTICS)
ai·自动化·llm·mock·lua·测试·tools
liulilittle3 天前
麻将 UI 层可观察行为(UI_BEHAVIOR)
ai·自动化·llm·mock·lua·测试·tools
liulilittle3 天前
C++ 引擎接口到 mock 的映射(INTERFACE_MAP)
ai·自动化·llm·mock·lua·测试·tools
SmalBox3 天前
02-04-原理篇-资源组织与依赖分析
unity3d·游戏开发
SmalBox5 天前
02-03-原理篇-资源打包流程详解
unity3d·游戏开发
bst@微胖子5 天前
Linux环境做LVM快照
lua