2016-04-01 8 views
1

iOS 9.3でJavaScriptCoreを複数のスレッドで使用しています。 1つのJSContextはすべてのスレッドで共有されます。アプリがクラッシュすることがあります。誰が何が起こっているのか分かっていますか?JavaScriptCoreクラッシュ

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 

答えて

0

1つのスレッドですべてのなJSContext関連法や関数を呼び出すようにしてください:

dispatch_queueを作成します。

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

呼び出しメソッドと関数:

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

// Async call 
dispatch_async(my_queue) { 
    .... 
}