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?
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.
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.