Ela*_*hts 14 asynchronous objective-c nsthread grand-central-dispatch ios
要在主线程上执行"stuff",我应该使用dispatch_async还是performSelectorOnMainThread?是否有首选方式,正确/错误和/或最佳做法?
示例:我在NSURLConnection sendAsynchronousRequest:urlRequest方法块中执行某些逻辑.因为我正在做主要视图的东西,比如呈现UIAlertView我需要UIAlertView在主线程上显示.为此,我使用以下代码.
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// code snipped out to keep this question short
if(![NSThread isMainThread])
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Oops!" message:@"Some Message" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
});
}
}];
Run Code Online (Sandbox Code Playgroud)
在同一个if(![NSThread isMainThread])声明中,我也称之为一些自定义方法.问题是,我应该dispatch_async使用上面使用的方法还是更好地使用performSelectorOnMainThread?例如,下面的完整代码:
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// code snipped out to keep this question short
if(![NSThread isMainThread])
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Oops!" message:@"Some Message" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
// call custom methods in dispatch_async?
[self hideLoginSpinner];
});
// or call them here using performSelectorOnMainThread???
[self performSelectorOnMainThread:@selector(hideLoginSpinner) withObject:nil waitUntilDone:NO];
}
}];
Run Code Online (Sandbox Code Playgroud)
仅供参考 - 如果我不在主线程上执行这些操作UIAlertView,我会在显示时看到几秒延迟,并且我在调试器中收到以下消息wait_fences: failed to receive reply: 10004003.我已经了解到这是因为你需要对主线程上的UI进行更改...如果有人想知道为什么我正在做我正在做的事情......
tor*_*ons 14
正如Josh Caswell提供的链接中所提到的,这两者几乎相同.最显着的区别是,performSelectorOnMainThread只会在默认的运行循环模式下执行,并且如果运行循环在跟踪或其他模式下运行,则会等待.但是,编写和维护代码存在一些显着差异.
dispatch_async具有编译器执行所有常规测试的巨大优势.如果您performSelectorOnMainThread在运行时错误地键入了该方法,而不是编译时间.dispatch_async使用__block限定符可以更容易地从主线程返回数据.dispatch_async使得处理原始参数变得更加容易,因为您不必将它们包装在对象中.然而,这带来了潜在的陷阱.如果您有指向某些数据的指针,请记住块捕获不会深度复制数据.另一方面,将数据包装在对象中,就像强制执行performSelectorOnMainThread深度复制一样(除非您设置了特殊选项).如果没有深层复制,您可能会遇到令人沮丧的间歇性错误.所以这意味着你应该char *在NSString打电话之前把东西包裹起来dispatch_async.| 归档时间: |
|
| 查看次数: |
27610 次 |
| 最近记录: |