Ios 如何使用GCD演示后台任务?
我想说明MBProgressHUD项的进度,但当我触发此方法时:Ios 如何使用GCD演示后台任务?,ios,objective-c,grand-central-dispatch,mbprogresshud,Ios,Objective C,Grand Central Dispatch,Mbprogresshud,我想说明MBProgressHUD项的进度,但当我触发此方法时: - (IBAction)signInBttn:(id)sender { MBProgressHUD *hudd = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; hudd.mode = MBProgressHUDModeAnnularDeterminate; hudd.labelText = @"Loading"; __block
- (IBAction)signInBttn:(id)sender {
MBProgressHUD *hudd = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hudd.mode = MBProgressHUDModeAnnularDeterminate;
hudd.labelText = @"Loading";
__block float value = 0;
for (int j = 0; j<2000; j++) {
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i = 0; i<20000 ; i++) {
}
value += 0.001;
dispatch_async( dispatch_get_main_queue(), ^{
hudd.progress = value;
});
});
}
}
-(iAction)登录TTN:(id)发件人{
MBProgressHUD*hudd=[MBProgressHUD showhuddeto:self.view动画:YES];
hudd.mode=mbprogresshuddode终止;
hudd.labelText=@“加载”;
__块浮点值=0;
对于(int j=0;j首先,如果您想延迟执行,请使用dispatch_after:因为可能是Clang正在优化您的循环(即使其不存在)
在该块中,在主线程上调用dispatch\u sync来更新UI,因为dispatch\u async不能保证“均匀”执行。类似这样的操作应该可以
for (...) {
dispatch_after(<some formula of i>, DEFAULT_PRIORITY, ^{
dispatch_sync(MAIN_QUEUE, ^{ hudd.progress = value });
}
}
(…)的{
在(,默认优先级,)之后调度^{
调度同步(主队列,^{hudd.progress=value});
}
}
在这种情况下,您可以通过将计数器的更新与UI中HUD的更新分离来解决问题。在WWDC 2012视频中,Apple将此称为“异步更新状态”
通常情况下,这是不必要的(大多数情况下,我们异步进行的工作速度很慢,因此不会出现问题),但如果执行的操作速度比UI希望的要快,则需要创建一个“调度源”对于这一点,我将用UIProgressView
来说明,但这同样适用于几乎所有的UI:
// create source for which we'll be incrementing a counter,
// and tell it to run the event handler in the main loop
// (because we're going to be updating the UI)
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());
// specify what you want the even handler to do (i.e. update the HUD or progress bar)
dispatch_source_set_event_handler(source, ^{
self.iterations += dispatch_source_get_data(source);
[self.progressView setProgress: (float) self.iterations / kMaxIterations];
});
// start the dispatch source
dispatch_resume(source);
// now, initiate the process that will update the source
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (long i = 0; i < kMaxIterations; i++)
{
// presumably, do something meaningful here
// now increment counter (and the event handler will take care of the UI)
dispatch_source_merge_data(source, 1);
}
// when all done, cancel the dispatch source
dispatch_source_cancel(source);
});
我将我的kmaxitations
常量定义如下:
static long const kMaxIterations = 10000000l;
与UI相同的基本问题是,在控件返回到运行循环之前,UI不会被重新绘制。正确的方法是使用某种计时器。空的for
循环是否应该是“暂停”?编译器很可能正在优化它。是的,我想用简单的方式模拟高级计算这对我在这方面使用GCD非常重要code@Fonix你真好!我把空的回复到睡眠!!!谢谢发送同步工作,但是限制了f后台进程与UI更新发生的速度。
static long const kMaxIterations = 10000000l;