【问题标题】:Does each addEventListener require a removeEventListener to prevent memory leak in Appcelerator每个 addEventListener 是否需要一个 removeEventListener 来防止 Appcelerator 中的内存泄漏
【发布时间】:2017-01-31 00:16:38
【问题描述】:

如果我有一个简单的警报对话框,例如

                  var dialog = Ti.UI.createAlertDialog({
                    cancel: 1,
                    buttonNames: ['OK'],
                    message: 'Here is message.',
                    title: 'Title'
                  });
                  dialog.addEventListener('click', function(e){
                    // do something
                  });
                  dialog.show();
                  dialog = null;

在一个窗口内。假设我关闭了那个窗口并且那个窗口实例没有分配任何变量。窗口应该被垃圾收集。 'dialog' 最终会在垃圾收集期间被释放,还是因为我从不调用 dialog.removeEventListener 它将永远存在于内存中?

【问题讨论】:

    标签: javascript ios memory-leaks titanium appcelerator


    【解决方案1】:

    在您的示例中,您确实不需要删除事件侦听器。

    为了防止内存泄漏,在这种情况下,您唯一需要做的就是确保声明 var dialog 而不仅仅是 dialog(您做得很好)。当窗口关闭时,窗口内本地范围内的所有 UI 元素都将从内存中删除。如果您声明全局引用,则可能会导致内存问题。

    现在在某些情况下您必须删除事件侦听器,而这些是自定义事件侦听器。专门为Ti.App 对象添加自定义事件而不删除它们会给您带来很多麻烦。我通常不建议添加任何内容,但如果你真的需要它,你应该确保将其删除,还要确保事件处理程序是一个命名函数。

    【讨论】:

    • 说得好,我再补充一件大家需要注意的事情:看看函数名:addEventListener,它不是setEventListener,多次调用addEventListener会导致调用在事件监听器被多次调用的后面,它不会覆盖之前添加的事件监听器
    • (我对 ECMAScript 和 DOM 非常熟悉,但对 Titanium 很陌生。)如果不删除事件,会出现什么“麻烦”(除了内存泄漏)listener 在那些其他情况下?为什么事件监听器是一个命名的函数很重要(Titanium 是否执行函数序列化?)?
    • 除了内存泄漏之外,您还可以在应用程序中看到奇怪的行为,例如多次触发事件,如果这些事件处理某些 UI,它可能会阻塞 UI 线程。 - 命名函数专门用于全局自定义事件,您可以在支持的事件上使用匿名函数,当 UI 组件不再使用或引用时它们将被删除
    • 多次调用 addEventListener 会为同一个事件产生多个事件回调是不对的!该事件的任何先前处理程序都会自动删除。
    • @DavidSpector 这只是部分正确。在 addEventListener() 调用中添加的任何先前使用相同参数的处理程序都将被替换。任何具有不同参数的参数都被添加到链中,并且每个都将被调用。使用未命名的函数执行此操作还有一个警告,因为它们被视为不同的。例如,参见developer.mozilla.org/en-US/docs/Web/API/EventTarget/… 的“多个相同的事件侦听器”部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 1970-01-01
    • 2010-09-21
    • 2016-07-10
    • 2011-12-05
    相关资源
    最近更新 更多