Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CFRunLoopTimer hash]: message sent to deallocated instance 0x60000037da00 #78

Open
shirakaba opened this issue Mar 11, 2017 · 0 comments

Comments

@shirakaba
Copy link

shirakaba commented Mar 11, 2017

Quite often when loading a webpage, XWVObject.denit() crashes my program, on the line webView.evaluateJavaScript(script, completionHandler: nil). This behaviour is inconsistent, so it is difficult to reproduce on demand. I have no experience debugging memory errors, so I don't know exactly what information to provide.

The line on which the program crashes:

xwvobject

Zombies profiling for all instruments:

all instruments

Zombies profiling for XWebView-related instruments:

xwebview instruments

Below is the general layout of my code (I have simplified it as much as possible).

This Swift function is called inside the ViewController's loadView():

func setUpWebView(){
    let jsContext : JSContext! = JSContext(virtualMachine: jsvm)
    jsContext.evaluateScript(myJavaScriptFile)
    let fn1 : JSValue! = jsContext.objectForKeyedSubscript("fn1")
    
    let userScript = WKUserScript(
        source: "\"use strict\"\n fn1(); \n" + fn1.description,
        injectionTime: WKUserScriptInjectionTime.atDocumentEnd,
        forMainFrameOnly: true
    )

    webView = WKWebView(frame: self.view.frame, configuration: WKWebViewConfiguration())
    webView!.configuration.userContentController.addUserScript(userScript)
    webView!.loadPlugin(Tokenizing(), namespace: "Tokenizing")
    webView!.navigationDelegate = self
}

This Swift class is loaded into the webView as a plugin:

class Tokenizing: NSObject {
    @objc func tokenize(_ callback: XWVScriptObject, _ input: String) {
        let inputText: NSString = input as NSString
        var tokens = [String]()

        // ...
        // Do tokenising here, and add to tokens array.
        // ...

        callback.call(arguments: [tokens], completionHandler: nil)
    }
    
    init() { }
}

This JavaScript function is added to webView.configuration.userContentController as a WKUserScript:

function fn1(){
  /* The callback that Swift's Tokenizing.tokenize calls. */
  function callback(tokens){
    var div = document.createElement('div');

    tokens.forEach(function(token) {
      var span = document.createElement('span');
      span.innerText = token;
      div.appendChild(span);
    });

    document.body.appendChild(div);
  }

  // We call the Swift function many times quickly.
  for(var i = 0; i < 500; i++) window.Tokenizing.tokenize(callback, ["some mock text to tokenize"]);
}

Edit: added mocked text data for JS function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant