1

我在 iOS 9.3 上使用带有多个线程的 JavaScriptCore。一个 JSContext 由所有线程共享。该应用程序有时会崩溃。有谁知道发生了什么?

func callFunction(function:String, date:NSDate, dataConfiguration:CDTimePeriodConfiguration, viz:CDViz, didFinish:((response:[String:AnyObject]?, error:NSError?) -> Void)?){

    guard let jsonString = self.jsonString(self.apiOptions(date, dataConfiguration: dataConfiguration, viz: viz)) else{
        let error = Error.errorWithCode(.ParametersMissing, failureReason: "Cannot create Rocket APIOptions")
        didFinish?(response: nil, error: error)
        return
    }

    let randomCallBackFunctionName = "callBackFromJS\(Int64(NSDate().timeIntervalSince1970 * 1000))\(random() % 100000)"

    let callBackClosure:  @convention(block) (response: [String:AnyObject]?, error: String?) -> Void = {
        [weak self]
        (response: [String:AnyObject]?, error: String?) -> Void in

        var errorMessage:String? = error

        if error == "null"{
            errorMessage = nil
        }

        dispatch_async(dispatch_get_main_queue()) {
            if let response = response where errorMessage == nil{
                didFinish?(response: response, error: nil)
            }
            else{

                if errorMessage == nil && response == nil{
                    errorMessage = "No reponse from Rocket"
                }

                let error = Error.errorWithCode(.RocketError, failureReason: errorMessage ?? "Rocket failed for unknown reason")
                didFinish?(response: response, error: error)
                self?.context.setObject(nil, forKeyedSubscript: randomCallBackFunctionName)
            }
        }
    }

    context.setObject(unsafeBitCast(callBackClosure, AnyObject.self), forKeyedSubscript: randomCallBackFunctionName)

    let js = "var options = \(jsonString) ; Rocket.\(function)(options).then(function(res) { \(randomCallBackFunctionName)(res, null); }).catch(function(err) { \(randomCallBackFunctionName)(null, err); })"
    self.context.evaluateScript(js)
}

0   JavaScriptCore                       0x000000018533f3d0 JSC::JSLock::lock(long) + 28
1   JavaScriptCore                       0x00000001850453f4 JSC::JSLockHolder::JSLockHolder(JSC::VM&) + 48
2   WebCore                              0x0000000185e079a0 WebCore::JSGlobalObjectCallback::call() + 64
3   WebCore                              0x0000000185aa3dd8 std::__1::__function::__func<WebCore::Document::postTask(WebCore::ScriptExecutionContext::Task)::$_0, std::__1::allocator<WebCore::Document::postTask(WebCore::ScriptExecutionContext::Task)::$_0>, void ()>::operator()() + 116
4   JavaScriptCore                       0x0000000184f35540 WTF::callFunctionObject(void*) + 28
5   JavaScriptCore                       0x0000000184f354c0 WTF::dispatchFunctionsFromMainThread() + 240
6   Foundation                           0x00000001826a7e20 __NSThreadPerformPerform + 336
7   CoreFoundation                       0x0000000181c9cefc __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 20
8   CoreFoundation                       0x0000000181c9c990 __CFRunLoopDoSources0 + 536
9   CoreFoundation                       0x0000000181c9a690 __CFRunLoopRun + 720
10  CoreFoundation                       0x0000000181bc9680 CFRunLoopRunSpecific + 380
11  WebCore                              0x0000000185779998 RunWebThread(void*) + 452
12  libsystem_pthread.dylib              0x000000018194fb28 _pthread_body + 152
13  libsystem_pthread.dylib              0x000000018194fa8c _pthread_start + 152
14  libsystem_pthread.dylib              0x000000018194d028 thread_start + 0
4

1 回答 1

1

尝试在一个线程中调用每个 JSContext 相关的方法和函数:

创建调度队列:

my_queue = dispatch_queue_create("com.example.subsystem.taskXYZ", NULL);

调用方法和函数:

...
// Sync call
dispatch_sync(my_queue) {
     ...
}

// Async call
dispatch_async(my_queue) {
    ....
}
于 2016-04-01T09:49:33.770 回答