我在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
答案 0 :(得分:0)
尝试在一个线程中调用每个与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) {
....
}