cocos小知识点-schedule和setTimeout以及setInterval区别

1. 执行方式

schedule 是 Cocos Creator 提供的一种调度方法,通常用于在每帧或者定时器周期内定期调用一个方法。你可以指定一个函数每隔一定的时间间隔执行一次。
setTimeout 用于 延迟执行一次 回调函数。指定一个延迟时间(毫秒)后,回调函数将会执行一次。
setInterval 会按照 固定时间间隔 重复执行回调函数,直到被手动清除。

2.基于帧更新 vs 基于事件循环

schedule是基于 Cocos Creator 的游戏主循环的,调度任务会按照 帧更新 的节奏,特别是如果你选择每帧执行的话。

//如果你传递 0 作为时间间隔,schedule 将会在每帧执行(例如每秒 60 帧),它会执行 60 次。帧率较低时(例如每秒 30 帧),它的执行频率也会降低。
this.schedule(function() {
    console.log('每帧执行');
}, 0); // 0表示每帧调用一次

// 每隔1秒执行一次
this.schedule(function() {
    console.log('每1秒执行一次');
}, 1); // 1秒调用一次

setTimeout 和 setInterval都是基于 JavaScript 的 事件循环 的。它们依赖于浏览器的定时器机制,不与游戏帧更新有关,因此不会受到游戏的帧率波动影响。

setTimeout(function() {
    console.log('延迟1秒执行');
}, 1000); // 1000毫秒(1秒)后执行

// 每隔1秒执行一次
const intervalId = setInterval(function() {
    console.log('每秒执行一次');
}, 1000); // 每隔1秒执行一次

// 如果想停止这个定时器
clearInterval(intervalId);

3 取消机制

schedule 在 Cocos Creator 中是通过 unscheduleunscheduleAllCallbacks 来取消的。
setTimeout 会返回一个定时器 ID,你可以通过 clearTimeout(id) 来取消已设置的定时任务。
setInterval 会返回一个定时器 ID,你可以通过 clearInterval(id) 来停止它的定期执行。

4.使用过程中需注意-防止内存泄漏

在 Cocos Creator 中使用 schedule 和 setTimeout、setInterval 时,如果没有适当的清理和管理,可能会导致 内存泄漏。这主要是因为这些定时器(或调度器)可能会继续保持对某些对象的引用,导致垃圾回收机制无法释放这些对象。为了避免内存泄漏,你需要确保定时器或调度任务在不需要时被正确地清理。

schedule
在 Cocos Creator 中,使用 schedule 通常 不会直接导致内存泄漏,当一个节点被销毁时(例如,调用了 destroy()),或者该节点进入了 禁用状态(例如,调用了 node.active = false),Cocos Creator 会自动调用 unscheduleAllCallbacks 来清除该节点上的所有调度任务。

在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述
setTimeout 和 setInterval 在执行回调时,回调函数通常会捕获其周围作用域的变量。如果回调中引用了组件实例、节点或其他大型对象,JavaScript 会保持这些对象的引用,直到定时器被清除。这意味着即使这些对象不再需要,它们也无法被垃圾回收。

cc.Class({
    extends: cc.Component,

    onLoad() {
        // 使用 setTimeout 延迟执行回调
        setTimeout(() => {
            // 回调函数中引用了 this,this 仍然会被保留,直到定时器被清除
            console.log(this.node.name);
        }, 1000);
    },

    onDestroy() {
        // 这里没有清除定时器
    }
});

完整的内存清理代码

cc.Class({
    extends: cc.Component,

    onLoad() {
        this.schedule(this.updateTask, 1); // 每1秒执行一次
        this.timeoutId = setTimeout(this.delayedTask, 2000); // 延迟2秒执行
        this.intervalId = setInterval(this.repeatedTask, 1000); // 每秒执行一次
    },

    updateTask() {
        console.log('1秒间隔任务');
    },

    delayedTask() {
        console.log('延迟2秒任务');
    },

    repeatedTask() {
        console.log('每秒重复任务');
    },

    onDestroy() {
        this.unschedule(this.updateTask); // 清除调度任务
        clearTimeout(this.timeoutId); // 清除 setTimeout
        clearInterval(this.intervalId); // 清除 setInterval
    }
});

避免长时间引用组件:尽量避免定时器回调中引用组件或大对象,尤其是当这些对象不再需要时。可以使用箭头函数或 bind 来确保 this 指向正确,但要小心避免在回调中持续引用组件。
使用 onDisable 或 onDestroy 进行清理:当你知道不再需要某个定时器或调度任务时,及时清除它们。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值