I'm having trouble with one of my Objective-C objects getting garbage
collected while I still have a reference to them. I'm using Mootools
classes:
var myClass = new Class({
initialize: function() {
this.object = ObjCClass.alloc.init;
},
doSomething: function() {
this.object.someMethodCall();
}
});
var myObject = new myClass();
myObject.doSomething();
The last call throws an error that result of expression this.object is
that [undefined] is not an object. I've logged this.object
immediately after creating it, and it's indeed an Objective-C object
of the correct type in the initialize function. I'm assuming that the
problem lies with this.object, which works fine in Mootools, but
evidently isn't strong enough of a reference to preserve the object in
JSCocoa.
Is this a bug in JSCocoa, or is there a workaround/fix that I'm not
aware of that I can make on my end?
Thanks in advance for your help! If you'd like to see the actual code
that's failing instead of the super abbreviated example above, let me
know and I'll get some links to the files on GitHub (this is all part
of a new JSCocoaLoader class living in the example branch).
Ian
> doSomething: function() {
> this.object.someMethodCall();
> }
Remove the parentheses. this.object.someMethodCall is the default
syntax for calling zero-param functions, just like [object
someMethodCall]. If your function returns void (converted to
undefined), Javascript tries to call a method with undefined as this,
then fails.
If you want to enable the use of parentheses, check useAutoCall. http://code.google.com/p/jscocoa/wiki/Autocall
You'll then have a new problem : you'll need to use parentheses to
force calling in some expressions. if (object.alloc.init) won't work,
you'll have to use (object.alloc.init()). That's a limitation of
JavascriptCore which I don't know how to get around.
Additionally, I'm working on adding an ObjC syntax to JSCocoa, just
like Obj-J and JSTalk. Using an ObjC syntax will make autocall
irrelevant.
-Patrick
I'm stumped. JSCocoa retains ObjC objects when boxing them, so they
live as long as they're bound to at least one Javascript variables.
I don't know Mootools, so off the top of my head you could debug these :
* When creating your object, store it in a global variable
> myGlobalVar = this.recipe = CETextRecipe.textRecipe; // Class
> method
Then check in insert if myGlobalVar is still alive.
* Store this from initialize and and insert in two global vars then
compare them -> maybe they're two different instances ?
* Log boxedObject in jsCocoaObject_finalize to see if it a
CETextRecipe is being destroyed.
-Patrick