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

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

原因:

被提前销毁定时器或协程

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

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

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

最稳妥处理:

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

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

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

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

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

根本保证处理:

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

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

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

最难受处理:

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

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

相关推荐
SmalBox6 小时前
05-03-源码-运行模式体系(PlayMode)
unity3d·游戏开发
笨鸟先飞的橘猫15 小时前
skynet热更新实现问题与排错记录
学习·lua·skynet
SmalBox2 天前
05-02-源码-全局入口与包管理(YooAssets & ResourcePackage)
unity3d·游戏开发
SmalBox2 天前
05-01-源码-运行时总览
unity3d·游戏开发
SmalBox3 天前
04-06-源码-调试与扫描工具
unity3d·游戏开发
开开心心_Every5 天前
黄金价格软件国内外价格实时监控超方便
运维·服务器·游戏·智能手机·pdf·lua·perl
SmalBox5 天前
04-05-源码-清单生成与构建报告
unity3d·游戏开发
SmalBox6 天前
04-04-源码-构建管线与任务系统
unity3d·游戏开发
笨鸟先飞的橘猫6 天前
C 扩展开发指南:从 Lua 到 skynet 的完整链路
c语言·lua
SmalBox7 天前
04-03-源码-构建映射与依赖分析(BuildMap)
unity3d·游戏开发