由于没有弱引用而导致的 JavaScript 问题

标签 javascript memory-leaks event-handling weak-references

假设我正在用 JavaScript 创建一个聊天系统。

var ChatController = function() {

    this.receiveMessageInteractor = new ReceiveMessageInteractor(this);

    // ReceiveMessageInteractor delegate

    this.didReceiveMessage = function(message) {
        // ...
    };

};

ChatController 还执行一些与为消息创建 html 相关的其他操作,但这在这里并不重要。

ChatController 将自己设置为 ReceiveMessageInteractor 的委托(delegate),当新消息到达时,它将调用 didReceiveMessage

var ReceiveMessageInteractor = function(delegate) {

    this.observer = NotificationCenter.addObserver('DidReceiveMessageNotification' , function(data) {
        var message = data['message'];
        // format some message data

        delegate.didReceiveMessage(message)
    });

};

ReceiveMessageInteractor 只是订阅一个通知(这里的 NotificationCenter 与 iOS 类似),对数据进行一些格式化,并将一个 message 对象传递给委托(delegate);

当聊天 View 离开屏幕时(html 被删除),我的 MenuController 停止持有指向 ChatController 的指针,在这种情况下,我希望它是连同 ReceiveMessageInteractorobserver 一起删除。

问题是 Javascript 没有弱引用,因此 ReceiveMessageInteractor 持有一个指向 ChatController 的指针,即使 ChatController 不是持有指向 ReceiveMessageInteractor 的指针,我的 ChatController 仍处于事件状态,因为通知回调持有指向它的指针 (delegate)。 因此,即使 ReceiveMessageInteractor 停止存在,当 MenuController 停止持有指向它的指针时,我的 ChatController 仍然不会消失(因为我不能在通知回调中有一个弱引用)。

如何解决这个问题?

最佳答案

How do I solve this problem?

通过了解 JavaScript。问题不在于“Javascript 没有弱引用”,问题在于你不知道如何在没有弱引用的情况下工作,因为你来自有弱引用的语言。

如何在任何其他本身没有弱引用的语言中删除该引用?就说C++吧。您会像每个人一样,包括您习惯的编译器/垃圾收集器/弱引用的实现者:您自己清理。

function ChatController() {

    this.receiveMessageInteractor = new ReceiveMessageInteractor(this);

    // ReceiveMessageInteractor delegate

    this.didReceiveMessage = function didReceiveMessage(message) {
        // ...
    };

    this.destroy = function destroy() {
        this.receiveMessageInteractor.destroy();
    };

};

function ReceiveMessageInteractor(delegate) {

    function callback(data) {
        var message = data.message;
        // format some message data

        delegate.didReceiveMessage(message);
    }

    this.observer = NotificationCenter.addObserver('DidReceiveMessageNotification', callback);

    this.destroy = function destroy() {
        // Or however you NotificationCenter works, I don't know
        NotificationCenter.removeObserver('DidReceiveMessageNotification', callback);
    };

};

观察者模式意味着资源管理,尽管它并不明显(“观察”关系如何成为资源??)。获取和释放。禁止手持。

此外,请注意风格的变化。请学习语言,使用原型(prototype),并且,尽管不是每个人都同意我的观点,但不要在构造函数中分配方法。

编辑:我忘记添加:ReceiveMessageInteractor?真的吗? MessageReceiver 或类似的东西有什么问题?

关于由于没有弱引用而导致的 JavaScript 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32258599/

相关文章:

iOS 内存泄漏, View Controller 的自定义 TabBar 失控分配

javascript - 尝试将事件处理程序放入单独文件时出现 Discord.js "cannot read properties of undefined"

android - 如何或在何处处理由 android actionbar 生成的点击事件

jquery - 我可以使用 jQuery 在准备好的文档上模拟单击吗?

javascript - 仅刷新某些 iframe,而不使用 jQuery 刷新整个页面

javascript - 谷歌地图 V3 : Comparing the distance of multiple points

javascript - 在不重绘的情况下将行添加到 JQuery DataTable

javascript - 使用 XPath 读取输入值,然后在 Greasemonkey 中使用

android - 内存不足内存泄漏问题

tomcat - 是否有使用 Tomcat 修复 BodyContentImpl jsp 标签内存泄漏的问题?