首页 > 系统相关 >如何避免在微信小程序中使用事件总线进行组件通信时出现内存泄漏?

如何避免在微信小程序中使用事件总线进行组件通信时出现内存泄漏?

时间:2024-10-24 19:18:34浏览次数:9  
标签:off 微信 总线 eventName callbacks 事件 组件 内存

  1. 理解内存泄漏问题的产生原因

    • 在微信小程序中使用事件总线进行组件通信时,内存泄漏可能是由于组件在销毁后仍然被事件总线持有引用,导致无法被垃圾回收机制正常回收。例如,组件订阅了事件总线的某个事件,当组件被销毁时,如果没有正确地取消订阅,那么事件总线中仍然保存着对该组件方法的引用,这部分内存就无法释放,从而产生内存泄漏。
  2. 正确地取消订阅(off方法)

    • 在组件生命周期方法中操作
      • 在组件的生命周期方法中,特别是detachedunload(适用于页面组件)方法中,应该取消对事件总线中事件的订阅。这是因为当组件被销毁时,它不应该再接收事件总线发布的事件。
      • 例如,假设在组件的attached生命周期阶段订阅了事件总线的一个事件,代码如下:
      const eventBus = require('../../event - bus.js');
      Component({
        attached() {
          eventBus.on('custom - event - name', this.handleEvent);
        },
        methods: {
          handleEvent(data) {
            console.log('Received data:', data);
          }
        }
      });
      
      • 为了避免内存泄漏,需要在组件的detached方法中取消订阅,修改后的代码如下:
      const eventBus = require('../../event - bus.js');
      Component({
        attached() {
          eventBus.on('custom - event - name', this.handleEvent);
        },
        detached() {
          eventBus.off('custom - event - name', this.handleEvent);
        },
        methods: {
          handleEvent(data) {
            console.log('Received data:', data);
          }
        }
      });
      
    • 确保off方法的正确使用
      • 当使用off方法取消订阅时,要确保传入的事件名称和回调函数与订阅时一致。如果传入的参数不准确,可能会导致无法正确取消订阅。
      • 例如,事件总线的off方法实现可能类似于以下代码:
      off(eventName, callback) {
        const callbacks = this.callbacks[eventName];
        if (callbacks) {
          const index = callbacks.indexOf(callback);
          if (index > - 1) {
            callbacks.splice(index, 1);
          }
        }
      }
      
      • 可以看到,它通过比较事件名称和回调函数在数组中的位置来进行取消操作。所以在使用off方法时,要保证传入的eventNamecallback是正确的。
  3. 管理事件总线的引用计数(如果适用)

    • 原理
      • 对于一些复杂的场景,可能需要更精细地管理事件总线的引用。可以通过引用计数的方式来确定何时可以安全地清理事件总线本身或者其内部的数据结构。例如,当没有任何组件订阅某个事件时,可以考虑清理与该事件相关的数据,以减少内存占用。
    • 示例实现
      • 可以在事件总线的onoff方法中添加引用计数逻辑。在on方法中增加引用计数,在off方法中减少引用计数,当引用计数为0时,清理相关数据。
      const eventBus = {
        callbacks: {},
        refCounts: {},
        on(eventName, callback) {
          if (!this.callbacks[eventName]) {
            this.callbacks[eventName] = [];
          }
          this.callbacks[eventName].push(callback);
          if (!this.refCounts[eventName]) {
            this.refCounts[eventName] = 0;
          }
          this.refCounts[eventName]++;
        },
        off(eventName, callback) {
          const callbacks = this.callbacks[eventName];
          if (callbacks) {
            const index = callbacks.indexOf(callback);
            if (index > - 1) {
              callbacks.splice(index, 1);
              if (this.refCounts[eventName]) {
                this.refCounts[eventName]--;
                if (this.refCounts[eventName] === 0) {
                  // 清理与该事件相关的数据,如callbacks[eventName]
                  delete this.callbacks[eventName];
                  delete this.refCounts[eventName];
                }
              }
            }
          }
        },
        emit(eventName, data) {
          const callbacks = this.callbacks[eventName] || [];
          callbacks.forEach(callback => {
            callback(data);
          });
        }
      };
      export default eventBus;
      
      • 这样,当所有订阅某个事件的组件都取消订阅后,与该事件相关的回调函数数组和引用计数都会被清理,有助于减少内存占用,避免潜在的内存泄漏。

标签:off,微信,总线,eventName,callbacks,事件,组件,内存
From: https://blog.csdn.net/alankuo/article/details/143196288

相关文章

  • Genymotion 模拟器上安装最新版本的微信并正常运行
    安装Genymotion安装步骤1安装虚拟机VirtualBox https://www.virtualbox.org/wiki/Downloads2注册Genymotion帐号 https://www.genymotion.com/account/create/3登录,下载并安装Genymotion https://www.genymotion.com/download/ android9版本的:  Genymotion-ARM-Tran......
  • Zabbix添加企业微信机器人告警
    环境查看系统环境#cat/etc/redhat-releaseCentOSStreamrelease9#uname-aLinuxCentOSStream9Zabbix2035.14.0-391.el9.x86_64#1SMPPREEMPT_DYNAMICTueNov2820:35:49UTC2023x86_64x86_64x86_64GNU/Linux软件环境#zabbix_server--versionzabbix_......
  • Linux内存泄露案例分析和内存管理分享
    一、问题近期我们运维同事接到线上LB(负载均衡)服务内存报警,运维同事反馈说LB集群有部分机器的内存使用率超过80%,有的甚至超过90%,而且内存使用率还再不停的增长。接到内存报警的消息,让整个团队都比较紧张,我们团队负责的LB服务是零售、物流、科技等业务服务的流量入口,承接上万个服......
  • 基于微信小程序的外卖点餐餐厅点餐美食点餐系统的设计与开发
    基于微信小程序的外卖点餐餐厅点餐美食点餐系统的设计与开发视频介绍:基于微信小程序的外卖点餐餐厅点餐美食点餐系统的设计与开发具体贴图链接:贴图链接缩略图如下:开发环境及工具:大等于jdk1.8,大于mysql5.5,idea,微信开发者工具技术说明:vue.js小程序java......
  • 基于微信小程序的健康生活运动社交系统的设计与开发
    基于微信小程序的健康生活运动社交系统的设计与开发视频介绍基于微信小程序的健康生活运动社交系统的设计与开发具体贴图链接:项目贴图缩略图如下:开发环境及工具:大等于jdk1.8,大于mysql5.5,idea,微信开发者工具技术说明:vue.js小程序javaspringbootmybatis......
  • 基于微信小程序的校园二手交易闲置二手交易系统的设计与开发
    基于微信小程序的校园二手交易闲置二手交易系统的设计与开发视频介绍基于微信小程序的校园二手交易闲置二手交易系统的设计与开发具体贴图链接:贴图链接缩略图如下:开发环境及工具:大等于jdk1.8,大于mysql5.5,idea,微信开发者工具技术说明:thymeleaf小程序java......
  • 微信小程序input框onfocus获取焦点的延迟问题
    今天敲代码,原本想实现的效果是:input框有placeholder,点击input,placeholder清空。好比上图,点击输入框,框内的“请输入四位XX”就会消失。原本想着是,给input框添加@focus,当input框获取到焦点的时候,清空placeholder。但是实际运行时候发现,placeholder清空......
  • fmql之Linux中I2C总线框架
    正点原子第44章        I2C zynqI2C  pcf8563芯片我们用的是ds3231. LinuxI2C总线框架 I2C总线驱动这部分内容是半导体厂商编写的。I2C总线设备   zynqI2C适配器驱动  I2C设备驱动编写 使用设备树 代码编写 设备......
  • CANOpen协议SDO中止报文(内存不足的解决方法)
    今天在开发过程中,使用SDO进行字符串传输的时候出现了错误,检查到SDO服务器返回的报文帧是一个中止帧,中止代码为0x05040005这时候去翻CIA301的手册查中止代码的含义为内存不足经过断点调试跟踪,发现在config.h中是一个配置宏设置的是32,而我的字符串的长度为50,所以就中止了,更改后......
  • C++11 中的内存对齐:alignas 与 alignof
    alignas和alignof是C++11引入的两个关键字,它们与内存对齐相关,帮助开发者控制和查询数据的内存对齐方式。内存对齐可以提高访问数据时的性能,特别是在处理硬件层面要求严格的场景下。1.alignasalignas是一个声明说明符,用来设置类型或对象的对齐方式。它允许开发者显式指定......