Ios 如何使用GCD演示后台任务?

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

我想说明MBProgressHUD项的进度,但当我触发此方法时:

- (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;