4

I am currently using backbone to implement my app. As part of memory management, I will trigger a teardown of all the views when I am switching views

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

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

Is this approach sufficient to ensure that most of the memory issues are resolved? The challenge I see here is that I need to track all the subviews of each view and call teardown for all main views and subviews as part of the cleanup.

I did some searching and found that backbone also has these two events: 'listenTo' and 'stopListening' where we control the binding of events to models at the view level.

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

My questions is, is there an overlap between my teardown implementation and using 'stopListening'? Can I just solely use 'stopListening' for memory management?

Zhen
  • 12,361
  • 38
  • 122
  • 199
  • @DerickBailey, I understand that you are the subject matter expert for backbone memory management =), hence tagging you here with the hope that you can help me out here. Thanks in advance! – Zhen Jan 15 '13 at 01:28

2 Answers2

4

The short answer is yes, there is an overlap.

The more complicated answer is listenTo/stopListening methods introduced in Backbone 0.9.9 already use on/off methods but with some useful addition – they store current event listeners in internal object called _listeners.

The benefit of using this object is that you always know full list of all your listeners – you can iterate over it and remove specific elements from it (remember that a listener is just a function and a function is just an object).

So, you can call it this way:

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)

So, using this method, you can convert your teardown method to something like this:

this.teardown = function(){
  this.stopListening();
  ...
}
Benji XVI
  • 2,192
  • 1
  • 25
  • 24
  • I guess I don't understand why the Backbone API takes a callback as the third parameter to Events.stopListening(obj,name,callback), anyone know? When would that callback be fired? – Alexander Mills Sep 09 '15 at 21:24
  • `stopListening` doesn't invoke the callback but allows the caller to target a specific handler that was passed in a previous call to `listenTo` instead of removing all handlers for the particular object and event-type tuple. – Spig Oct 08 '15 at 14:07
3

I'd recommend using listenTo method. The niceness of it is that when you use the remove method on your view, it will automatically unbind (call stopListening) on what it's listening to. According to Derrick Bailey, it also unbinds the events under the events property.

What I will do, since I am in the process of upgrading my app to 0.9.9 from 0.9.2 (which actually still works so far), is just switch around all of my ons/offs to listenTo and stopListening. I also, mostly, have close methods on there. I will, however, still call undelegateEvents, just in case. Doesn't hurt to know that you're still getting rid of the event listening.

Allen
  • 794
  • 1
  • 6
  • 19