让我们说我在javascript中创建了一个聊天系统。
var ChatController = function() {
this.receiveMessageInteractor = new ReceiveMessageInteractor(this);
// ReceiveMessageInteractor delegate
this.didReceiveMessage = function(message) {
// ...
};
};
ChatController
还会做一些与为消息创建html相关的其他内容,但这并不重要。
ChatController
将自己设置为ReceiveMessageInteractor
的代表,当新邮件到达时,didReceiveMessage
会调用var ReceiveMessageInteractor = function(delegate) {
this.observer = NotificationCenter.addObserver('DidReceiveMessageNotification' , function(data) {
var message = data['message'];
// format some message data
delegate.didReceiveMessage(message)
});
};
。
NotificationCenter
ReceiveMessageInteractor只是订阅了一个通知(这里的message
类似于iOS),对数据做了一些格式化并将MenuController
对象传递给了委托;
当聊天视图进入屏幕时(html被删除),我的ChatController
停止了指向ReceiveMessageInteractor
的指针,在这种情况下,我希望将其删除,以及observer
和ReceiveMessageInteractor
。
问题是Javascript没有弱引用,因此ChatController
持有指向ChatController
的指针,即使ReceiveMessageInteractor
没有指向{{1}的指针我的ChatController
仍然存活,因为通知回调是一个指向它的指针(delegate
)。
因此,即使ReceiveMessageInteractor
已停止存在,当ChatController
停止指向它时,我的MenuController
仍然不会消失(因为我在通知中无法提供弱引用)回调)。
如何解决这个问题?
答案 0 :(得分:1)
如何解决这个问题?
通过了解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);
};
};
观察者模式意味着资源管理,即使它并不明显(如何观察"关系是资源?)。获取并发布。没有手握。
另外,请注意样式的变化。请学习语言,使用原型,虽然不是每个人都同意我的观点,但不要在构造函数中分配方法。
修改:我忘了添加:ReceiveMessageInteractor
?真? MessageReceiver
或其他什么东西出了什么问题?
答案 1 :(得分:1)
你的问题不在于没有弱引用。您的所有对象都会继续有一个硬参考,所有这些都来自您的NotificationCenter
。
NotificationCenter
引用了数据处理程序,该数据处理程序具有对其父ReceiveMessageInteractor
实例的闭包访问权限,以及对delegate
变量的访问权限。从其他位置删除对delegate
的引用不会破坏匿名函数对它的访问权限,因此它会保留。
您需要做的是向每个被删除时调用的Controller添加.cleanup()
方法。
在ChatController.cleanup()
方法中,您可能希望调用一个方法来移除观察者,类似于this.receiveMessageInteractor.observer.unsubscribe()
。
应在NotificationCenter中定义.unsubscribe()
方法,并删除您在function(data) { ... }
中定义的.addObserver()
方法,该方法不受任何数据结构的限制(或更深层次)。
这与Facebook在其React框架+ Flux架构中使用的模式相同。每个组件都有一个componentWillUnmount()
方法,可以帮助您清理数据事件处理程序,就像您的一样。