我在修改线程内的视图时遇到问题.我试图添加一个子视图,但显示大约需要6秒或更长时间.我终于搞定了,但我不知道究竟是怎么回事.所以我想知道为什么它有效,以下方法之间有什么区别:
//this worked -added the view instantly
dispatch_async(dispatch_get_main_queue(), ^{
//some UI methods ej
[view addSubview: otherView];
}
//this took around 6 or more seconds to display
[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView
waitUntilDone:NO];
//Also didnt work: NSNotification methods - took also around 6 seconds to display
//the observer was in the viewController I wanted to modify
//paired to a method to add a subview.
[[NSNotificationCenter defaultCenter] postNotificationName:
@"notification-identifier" object:object];
Run Code Online (Sandbox Code Playgroud)
作为参考,这是在ACAccountStore类的Completetion Handler中调用的.
accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
if(granted) {
//my methods were …Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中使用了GCD和performSelectorOnMainThread:waitUntilDone,并且倾向于认为它们是可互换的 - 也就是说,performSelectorOnMainThread:waitUntilDone是GCD C语法的Obj-C包装器.我一直在考虑这两个命令是等价的:
dispatch_sync(dispatch_get_main_queue(), ^{ [self doit:YES]; });
[self performSelectorOnMainThread:@selector(doit:) withObject:YES waitUntilDone:YES];
Run Code Online (Sandbox Code Playgroud)
我不对吗?也就是说,performSelector*命令与GCD命令有区别吗?我已经阅读了很多关于它们的文档,但还没有看到明确的答案.
iphone multithreading objective-c grand-central-dispatch ios
我发现了一个似乎导致WebKit陷入僵局的问题.如果我从我的主线程运行此代码,我正确地看到一个警报.我可以点击警报上的"确定"按钮,它会解散并且一切正常:
[theWebView stringByEvaluatingJavaScriptFromString:@"alert('hi');"];
Run Code Online (Sandbox Code Playgroud)
如果我进行了一些修改,那么警报信息仍会出现,但是无法点击"确定"按钮 - 您无法关闭警报,如果您闯入应用程序,它将挂在stringByEvaluatingJavaScriptFromString通话中:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[theWebView stringByEvaluatingJavaScriptFromString:@"alert('hi');"];
});
});
Run Code Online (Sandbox Code Playgroud)
这两者中唯一不同的是,在第二个中,它在调度队列的上下文中在主线程中运行JS.
另一方面,如果我执行以下操作,则不会发生挂起:
- (void) showHi:(id) it
{
[(UIWebView*)it stringByEvaluatingJavaScriptFromString:@"alert('hi');"];
}
....
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self performSelectorOnMainThread:@selector(showHi:) withObject:theWebView waitUntilDone:NO];
});
Run Code Online (Sandbox Code Playgroud)
有人可以对导致挂起的问题有所了解吗?
编辑:
相关问题:
使用dispatch_async或performSelectorOnMainThread在主线程上执行UI更改?
什么是主队列上的performSelectorOnMainThread和dispatch_async之间的区别?
Grand Central Dispatch(GCD)与performSelector - 需要更好的解释
非常相似的问题:
当使用GCD调用时,UIWebView stringByEvaluatingJavaScriptFromString在iOS5.0/5.1上挂起