Titanium events at launch after controller destruction

  • Application type: mobile
  • Titanium SDK: 3.1.1.GA
  • Platform and Version: iOS 6.1
  • Device: iOS Simulator
  • Host Operating System: OSX 10.8.4
  • Titanium Studio: 3.1.1.201306112235

parent_controller.js:

_.each(category, function(inventory_item, index, list) { var row = Alloy.createController('inventory_list_row', { selectedBackgroundColor: '', data: inventory_item }); row.destroy(); row = null; }); Ti.App.fireEvent('checkIn'); 

inventory_list_row.js:

 Ti.App.addEventListener('checkIn', function(e) { console.info('Checking In: ' + args.data.title); }); 

Foreword: The above code is irrigated to prove the point. I know that it really does nothing, but it is really problematic.

The code in parent_controller.js may run several times depending on the user interaction in my Titanium Mobile iPad application. If the code above only works once, everything will be fine. Each time the above code is run, the previous controllers are some of them left in memory and still exciting events.

For example, suppose that the first time the code is run, 3 inventory_list_row controllers are generated. In the console, I will see that the messages "Checking In" are displayed as expected. The second time it starts, I will see that the message β€œChecking In” appears in the console, etc. etc.

Why is this, and what can I do to prevent it? You can see that I tried using .destroy and setting the string to zero to no avail.

+4
source share
2 answers
  • You may need to remove the eventListener in the controller destruction method.
  • Why are you using a global event listener to manage local events?
  • maybe you can use callback instead

These are just some quick observations without having to write any code to confirm. Honestly, I do not use global events at all.

+1
source

Here is a quick solution that implements what Aaron said in his first pool, just add this method to your inventory line controller.

 // Here is the event listener function var checkInListenFunction = function(e) { console.info('Checking In: ' + args.data.title); } // Add just like in your code Ti.App.addEventListener('checkIn', checkInListenFunction); // When this controller is destroyed you have to remove the listener as well // OR the controller will forever stay in memory, since you access variables // from the controllers scope! exports.destroy = function() { // Remove the listener first Ti.App.addRemoveListener('checkIn', checkInListenFunction); $.destroy(); } 

Global event listeners are saved until you delete them, which means that (in accordance with the rules of the javascript area), any variable that they access is automatically saved. Since you access args.data.title inside your event listener, and this variable is bound to the inventory_list_row controller, the interpreter holds the controller (or most of it) in memory no matter what you do, so these events will continue to fire long after of how you destroy and destroy them.

I would not use global event listeners, too much confusion and the possibility of a memory leak in a limited memory space. Take Aaron's suggestions and make this callback or fire up a local event on the controller itself.

EDIT:

This can be done if you want the listener to listen only once, just delete it, simply:

 Ti.App.addEventListener('checkIn', function(e) { console.info('Checking In: ' + args.data.title); Ti.App.removeEventListener(this); }); 
0
source

Source: https://habr.com/ru/post/1490393/


All Articles