Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

Objects passed from global context to subcontext and then back to global context lose identity

I've found that objects passed to a sub-context and then passed back to the parent context are not the same as the original object in the parent context. Has anybody else experienced this?

I am using a TableView to display a list of cars implemented in a CarList.js file. I am using another file, CarInfo.js, to display information about the car when a row is clicked.

Here's the gist of my code:

##CarList.js

// populate rows for the table view from the carList model.
var carRows = [];
carList.each(function(car) {
  carRows.push({ title : car.name, hasChild : true, car : car });
});

var carsTableView = Titanium.UI.createTableView({
    data : carRows
});

carsTableView.addEventListener('click', function(e) {

  var carInfoWindow = Titanium.UI.createWindow({ url : 'CarInfo.js' });

  // pass along the car that the view should be rendered for and 
  // a callback for saving the car to the data layer.
  carInfoWindow.car = e.rowData.car;
  carInfoWindow.saveCar = function(carFromSubContext) {
    for ( var i = 0; i < carList.length; ++i ) {
      if (carList[i] === carFromSubContext) {
        // NEVER HAPPENS
        alert( 'Car passed from sub-context exists in parent context!' );
      }
    }
  }

  Titanium.UI.currentTab.open(carInfoWindow,{animated:true});
});

##CarInfo.js

window =  Titanium.UI.currentWindow;
...
saveButton.addEventListener('click', function() {
  // update attributes of the car from the view
  window.car.name = nameField.value;
  ...

  // save it
  window.saveCar(car);
});

The alert() call in the saveCar() callback on the carInfoWindow is never hit. I've inspected the attributes of the cars in carList and carFromSubContext, and there is a car object in carList that has the exact same attributes as carFromSubContext, but it does not pass the identity test in saveCar().

What gives?

— asked May 12th 2010 by Donnie Tognazzini
  • subcontext
  • subcontexts
  • window
  • windows
0 Comments

5 Answers

  • Accepted Answer

    @David - Regarding:
    "Cross window messaging operates on the same principles as the fire event"

    Yeah, I was beginning to believe that. Seems likely since windows run in their own threads and if things weren't cloned you'd have to worry about synchronized access to the data. Still though, references to objects and functions passed down from the parent to the sub context are not null as the Passing Data section of the doc on Window discusses and as my example shows.

    To add to the confusion, in my example, the saveCar() callback lives in the parent context and is called by the sub context but accesses data in the parent context (i.e. the carList array). How is the carList variable accessible?

    If objects are cloned when passed to sub contexts then objects referenced internally by saveCar() (i.e. carList) would be missed as they are not known about yet. Perhaps the JS-internal objects comprising the scope chain are cloned during this step as well? Or perhaps, the scope chain is not cloned, but when looking up variable references through the scope chain there is something that identifies that the variable lives in a different context and when this happens it grabs a mutex before accessing the data?

    So, I'm not really sure what to believe at this point. Perhaps cross window messaging is tasked to a single thread that grabs per-context locks? I don't know…

    Lacking an authoritative answer (something I was hoping to get from asking the question), the only remaining alternative is to splunk through the source code; something I don't have time to do. This issue and some others (see below) have resulted in me completely avoiding the use of sub contexts altogether. It would be nice to see examples of how sub contexts can be used in an MVC structure containing an app-wide data layer shared across many contexts… I can't wait for that now.

    Other issues with sub contexts:

    TableViews Best Practice: Using Window Constructor to decorate prior to opening vs. using sub-contexts

    Reusing util code in windows created from TableViews

    — answered May 14th 2010 by Donnie Tognazzini
    permalink
    0 Comments
  • This is documented in the last bullet point on events here https://developer.appcelerator.com/apidoc/mobile/1.2/Titanium.UI.Window-object

    The solution to the problem is also outlined with sending events to a window from the global context and vice versa.

    — answered May 12th 2010 by David Ashwood
    permalink
    0 Comments
  • As far as I know, objects are serialized for events. Perhaps you could add an id field and check that instead.

    — answered May 12th 2010 by Damien Elmes
    permalink
    0 Comments
  • @David - The last bullet point talks about sending events through fireEvent(). I am not sending events. See my code in the question.

    @Damien - Yeah, this is what I do. Then I have to copy over all the attributes from the object from the sub-context to the origin object in the parent context. I was hoping I wouldn't have to do this.

    — answered May 13th 2010 by Donnie Tognazzini
    permalink
    0 Comments
  • Cross window messaging operates on the same principles as the fire event I believe and as such:
    "You can only send JSON-serializable data in a fireEvent. If you attempt to send objects that have function references, they will be null." applies.

    Each window runs in it's own thread and objects are cloned (json serialised) - rather than being a reference.

    — answered May 13th 2010 by David Ashwood
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.