Skip to content

Retain cycle in ACEBridgedObject #17

@jzrake

Description

@jzrake

When adding an instance of ACEView as a subview, the instance is never deallocated after it was removed from its superview.

If the instance is never added as a subview, the application crashes with SIGABORT in ACEView.webView, when the instance goes out of scope:

objc[63279]: Cannot form weak reference to instance (0x101d13840) of class ACEViewSwift.ACEView. It is possible that this object was over-released, or is in the process of deallocation.

at

open func webView(_ sender: WebView!, didFinishLoadFor frame: WebFrame!) {
  // ...
  context.aceView = self // <-- crashes here
}

This problem is caused by a reference cycle between the JSContext instance and the ACEView instance. The cycle is formed at line 443 in the ACEContext implementation, in turn called from the assignment in webView referenced above.

I'm no expert on the Javascript Core stuff, but I suspect facilities like JSManagedValue are intended to deal with this type of reference cycle. The article here is potentially helpful:

https://medium.com/swift-programming/from-swift-to-javascript-and-back-fd1f6a7a9f46

A warning about holding JSValue objects in native objects exported to JS also appears here:

https://developer.apple.com/documentation/javascriptcore/jsmanagedvalue

I tried changing the type of ACEBridgedObject.jsValue to JSManagedValue. This did not cause any further problems, but it also did not resolve the reference cycle.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions