Export to GitHub

jscocoa - GarbageCollection.wiki


JSCocoa Garbage Collection uses JavascriptCore's Garbage Collection engine. You can safely manipulate Objective-C objects without fear of them being deallocated as JSCocoa retains and releases them for you. But you have to be careful when allocating objects yourself and you have to know when they can be deallocated.

When are ObjC objects actually released ?

ObjC objects are released during JavascriptCore Garbage Collection when no Javascript variables are using them anymore.

Getting objects back from the runtime in the global scope (not in a function)
var myObject = anObject.getSomeObject(2, 3)
myObject becomes collectable when you set myObject = null.

Getting objects back from the runtime in a function
var myObject = anObject.getSomeObject(2, 3)
Provided you only use myObject in this function, myObject becomes collectable when you exit the function. If you return it and use it in the global scope, set it to null

Allocating objects with instance
var myObject = MyObject.instance
Set myObject to null if you're in the global scope. In a function, it will be collectable on function exit.

Allocating objects with alloc/init
var myObject = MyObject.alloc.init
Call myObject.release and set myObject to null if you're in the global scope. If in a function, myObject.release will suffice.

WARNING ! Forgetting the var declarator in a function will declare a variable in the global scope
In a function, assigning to an undefined variable myVar = someObjCObject will create myVar in the global scope. You'll need to set it to null to make it collectable. To prevent that, always declare your variables with var myVar = someObjCObject


That's it ! To sum up, use instance to allocate and set your variables to null when you're not in a function.











Some behind-the-scenes info follows :

Live instance count

For JSCocoa classes only JSCocoa logs instance count. Call JSCocoaController.logInstanceStats

Manually start Garbage Collection

Call JSCocoaController.garbageCollect. You need to do that only if you want an object to be released NOW.

Javascript name binding

Javascript does not copy objects when evaluating myVar = someObject; myVar2 = someObject — a new name is bound to the object, therefore both variables myVar and myVar2 point to someObject. JavascriptCore's Garbage Collector handles that itself, there's no extra retaining or releasing happening here.

JSCocoa boxes ObjC objects

When evaluating NSWorkspace.sharedWorkspace.activeApplication, JSCocoa gets called back by Javascript and has to give back Javascript objects to Javascript. In that case, JSCocoa will :

  • be called a first time by JavascriptCore asking for NSWorkspace. JSCocoa finds the matching ObjC class and boxes it back to Javascript
  • be called a second time by JavascriptCore asking for the property sharedWorkspace of NSWorkspace — JSCocoa calls the matching method and boxes it back to Javascript
  • be called a third time by JavascriptCore asking for the property activeApplication of sharedWorkspace — JSCocoa calls the matching method and boxes it back to Javascript

That's how the bridge works : JavascriptCore can only manipulate Javascript objects so JSCocoa boxes ObjC objects in Javascript objects. Each time this happens the boxed object is retained, each time the Javascript object is destroyed the boxed object is released. That's why you can use any object you get from any method call safely as it will be released automatically when Garbage Collection happens.

Boxing is done with JSCocoaPrivateObject. More in SampleBridgeEvaluation.