我通过以下方法在Objective-C中发出异步请求:
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
NSInteger code = [httpResponse statusCode];
if (code == 200){
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// Escape single quotes
jsonString = [jsonString stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"];
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat: @"window.displayVotes('%@')", jsonString]];
} else {
// Error
...
}
}];
这段代码一直很好,直到我到达stringByEvaluatingJavaScriptFromString
,代码退出时会显示以下信息:
1 0x7fff891faf1f WebCore::ScriptController::evaluateInWorld(WebCore::ScriptSourceCode const&, WebCore::DOMWrapperWorld*)
2 0x7fff891fadc9 WebCore::ScriptController::evaluate(WebCore::ScriptSourceCode const&)
3 0x7fff89338466 WebCore::ScriptController::executeScript(WebCore::ScriptSourceCode const&)
4 0x7fff89338290 WebCore::ScriptController::executeScript(WTF::String const&, bool)
5 0x7fff8c85265e -[WebFrame(WebInternal) _stringByEvaluatingJavaScriptFromString:forceUserGesture:]
6 0x100008fc9 __31-[CCAppDelegate getVotes:name:]_block_invoke
7 0x7fff90da26ad __67+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]_block_invoke_2
8 0x7fff90c2c0b5 -[NSBlockOperation main]
9 0x7fff90c0b8a1 -[__NSOperationInternal _start:]
10 0x7fff90c0b54b __NSOQSchedule_f
11 0x7fff915a62ad _dispatch_client_callout
12 0x7fff915aa7ff _dispatch_async_redirect_invoke
13 0x7fff915a62ad _dispatch_client_callout
14 0x7fff915a809e _dispatch_root_queue_drain
15 0x7fff915a9193 _dispatch_worker_thread2
16 0x7fff8d179ef8 _pthread_wqthread
17 0x7fff8d17cfb9 start_wqthread
我不完全确定为什么会发生这种情况(因此我来到SO),但我的猜测是,这与self.webView
对不同线程的可用性有关。我会将它保留为同步请求,但我请求的URL可能需要一段时间才能返回,这会阻塞UI。
有没有办法解决这个问题?我尝试将stringByEvaluatingJavaScriptFromString
代码移动到它自己的方法,然后在完成回调中调用[self thatMethod]
,但它产生了类似的错误。
答案 0 :(得分:2)
我可能会鼓励您保持连接异步,但请尝试将stringByEvaluatingJavaScriptFromString
发送到主队列(或使用[NSOperationQueue mainQueue]
作为queue
的{{1}}参数; sendAsynchronousRequest
参数指定完成块将在哪个队列上运行,但原始请求仍然以异步方式运行。
这样,您可以保留请求的异步性质,但要确保在主队列上进行Web视图交互。