4

我目前正在使用骨干网来实现我的应用程序。作为内存管理的一部分,我将在切换视图时触发所有视图的拆卸

teardown: ->
  for viewName, view of @subViews
    view.teardown()
  for object, events of @objectEvents
    @_handleObjectEvents("off", object, events)

  @off()
  @remove()
  @undelegateEvents()
  @

这种方法是否足以确保大多数内存问题得到解决?我在这里看到的挑战是我需要跟踪每个视图的所有子视图,并在清理过程中调用所有主视图和子视图的拆卸。

我做了一些搜索,发现主干也有这两个事件:“listenTo”和“stopListening”,我们在视图级别控制事件与模型的绑定。

view.listenTo(model, 'change', view.render);
view.stopListening(model);

我的问题是,我的拆卸实现和使用“stopListening”之间是否存在重叠?我可以只使用“stopListening”进行内存管理吗?

4

2 回答 2

4

简短的回答是肯定的,有重叠。

更复杂的答案是 Backbone 0.9.9 中引入的 listenTo/stopListening 方法已经使用了开/关方法,但还有一些有用的附加功能——它们将当前事件侦听器存储在称为 _listeners 的内部对象中。

使用这个对象的好处是你总是知道所有监听器的完整列表——你可以迭代它并从中删除特定的元素(记住监听器只是一个函数,一个函数只是一个对象)。

所以,你可以这样称呼它:

this.stopListening(emitting_object, ["reset", "add"]) // Removes listeners  for "reset" and "add" on emitting_object
this.stopListening(emitting_object) // Removes all listeners on emitting_object
this.stopListening() // Iterates over _listeners object and removes all listeners (probably the most usable case)

因此,使用此方法,您可以将拆卸方法转换为以下内容:

this.teardown = function(){
  this.stopListening();
  ...
}
于 2013-01-16T06:23:09.340 回答
3

我建议使用 listenTo 方法。它的好处在于,当您在视图上使用 remove 方法时,它会自动取消绑定(调用 stopListening)它正在收听的内容。根据 Derrick Bailey 的说法,它还解除了 events 属性下的事件的绑定。

我将要做的,因为我正在将我的应用程序从 0.9.2 升级到 0.9.9(到目前为止实际上仍然有效),只是将我所有的开关切换到 listenTo 和 stopListening。大多数情况下,我也有关闭方法。但是,我仍然会调用 undelegateEvents,以防万一。知道您仍在摆脱事件侦听并没有什么坏处。

于 2013-01-16T04:29:32.837 回答