Passing weak references to JSContext

I am using JavaScriptCore to pass data between javascript and swift. Here is a minimal reproducible example of what I am trying to accomplish:

class SomeClass: NSObject {
    let context: JSContext

    override init() {
        context = JSContext(virtualMachine: AppDelegate.jsvm)!
        super.init()
        context.name = "\(Self.self)"
        context.isInspectable = true
        context.setObject(self, forKeyedSubscript: "window" as NSString)
    }
}

This code introduces retain cycle as context is keeping strong reference to the SomeClass passed. Is there any way I can make context keep a weak reference instead?

1 Like

Is there any way I can make context keep a weak reference instead?

No.

You might be able to make some progress by leaning into JavaScript’s WeakRef concept but I don’t think that’ll help in this case because I doubt that the JavaScript code running within this context is expecting to find a WeakRef in window.

This code introduces retain cycle as context is keeping strong
reference to the SomeClass passed.

Right. You have the standard options here:

  • You can introduce an ‘invalidate’ method that removes window from the global object.

  • You can factor the window-y stuff out into a separate object and have that delegate back up to your SomeClass object via a weak reference.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

2 Likes
  • You can introduce an ‘invalidate’ method that removes window from the global object.

This is exactly what I am trying to avoid as I have to make lots of changes for this and this might be prone to error in case of invalidate is missed somewhere.

  • You can factor the window-y stuff out into a separate object and have that delegate back up to your SomeClass object via a weak reference.

This works but the deinit method is invoked with a delay. This could be due to to JavaScript's garbage collection algorithm. I opted for similar approach to this, instead of creating a wrapper object I created a closure that stores weak reference to object and returns the weak referred object.

I earlier tried this approach but due to the delay thought this doesn't work. Thanks for pointing this approach.