Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-4242] Calling Ti.API.info from global object reference in sub-context causes event exception

GitHub Issuen/a
TypeBug
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2011-06-03T14:36:32.000+0000
Affected Version/sRelease 1.7.0
Fix Version/sSprint 2011-22
ComponentsiOS
Labelsti.api
ReporterJeffrey Clark
AssigneeBlain Hamon
Created2011-05-18T11:11:44.000+0000
Updated2011-06-06T14:04:56.000+0000

Description

The following code produces error (below) as summarized on iOS only. The error can be circumvented by placing a call to everywhere.test() or Ti.API.info before it is called by the event in win.js (sub-context reference).
var everywhere = {
    test: function() {
        Ti.API.info('this is a test');
    }
};

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

win.everywhere = everywhere;
win.open();
({
    win: Ti.UI.currentWindow,
    everywhere: Ti.UI.currentWindow.everywhere,
    init: function() {
        var self = this;
        var button = Ti.UI.createButton({
            title: "click me"
        });
        button.addEventListener('click', function(e) {
            self.clicked();
        });
        this.win.add(button);
    },
    clicked: function() {
        this.everywhere.test();
    }
}).init();
{noformat} [WARN] [object TopTiModule] tried to note the callback for API in the wrong thead. [WARN] Exception in event callback. { line = 6; message = "-[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: API)"; sourceId = 116344464; sourceURL = "file:///scopebug/Resources/app.js"; } {noformat}

Comments

  1. Jeffrey Clark 2011-05-18

    Other users are reporting what appears to be the same issue in [a community support question](https://developer.appcelerator.com/question/119751/errors-with-latest-builds-17x-r3bed52c7-and-18x-r5a5f4522#header). I entered another ticket (TC-10) which, although the example code is different, it may fall under the same problem.
  2. Jeffrey Clark 2011-05-19

    [Comment on github from development team](https://github.com/appcelerator/titanium_mobile/commit/7bef2bd0bcb7abbded1b9cccbbd187ee056788d7#commitcomment-390814)
  3. Paul Dowsett 2011-05-30

    Tested and works on Android 2.2, Titanium SDK 1.7.0 (05/27/11 17:53 8be59d3...)
  4. Dawson Toth 2011-05-31

    A client is watching this now as well.

    Associated Helpdesk Ticket

    http://appc.me/c/APP-367438
  5. Blain Hamon 2011-06-03

    The fix won't make it into 1.7.0, but there's a workaround. The workaround is to put, in app.js, put as line 1: Ti.API; Cross-context function calls are dangerous things (It's better to use event handlers, because of threading issues. (JS objects in JSCore are not threadsafe, and cross-context function calls mean you could be modifying the same JS object at the same time.) When you first refer to a module, that's when it's generated and attached to the Titanium namespace. However, when you're doing a cross-context call, the Titanium namespace the function is accessing is NOT the Titanium of the context calling the function. Because it's the wrong namespace, the context that owns it refuses to register the module because it's the wrong thread (safety reasons). However, if the module was already registered in the right context, things are fine. We pre-register UI module since it will be used. Since API module is also common, it will now be pre-registered. However, other modules won't be pre-registered.
  6. Blain Hamon 2011-06-03

    It's still not good to call cross-context, but pre-loading API is innocuous enough.
  7. Eric Merriman 2011-06-06

    Verified fixed with Verizon iPhone 4 (4.2.8) , Titanium Studio, build: 1.0.0.201106021621, Titanium SDK version: 1.8.0 r477c7b27. No exception, simply a warning: [WARN] (null)->(null) [0]->[object APIModule] is being made in a thread not owned by

JSON Source