Skip to content

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

@shirakaba

Description

@shirakaba

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions