当可可应用中的主线程被阻止时,UI不会更新 [英] UI does not update when main thread is blocked in Cocoa app

查看:96
本文介绍了当可可应用中的主线程被阻止时,UI不会更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在主线程中使用NSProgressIndicator来更新我的整个方法时的进度.现在,当我最终从另一个类文件中调用一个对象,并等待该对象返回主线程的值时,我注意到NSProgressIndicator将消失.我知道这是因为主线程被阻塞,直到我从另一个对象获得返回值为止.

I am using a NSProgressIndicator in my main thread to update on progress as I run through my entire method. Now when I end up calling an object from a different class file, and wait for that object to return to a value to my main thread, I notice that the NSProgressIndicator will disappear. I understand that this is because the main thread is blocked until I get the return value from the other object.

所以我的问题是在主线程中更新UI而不阻塞它并让其他对象在后台运行并根据需要将值返回到主线程的推荐方法是什么?我知道如何使用块,但不允许块操作返回值. 我需要的是可以帮助此伪代码的东西:

So my questions is what is the recommended way for updating UI in the main thread without blocking it and having other objects run in the background and return values to the main thread as needed. I know how to use blocks but blockoperations are not allowed to return values. What I need is something that helps this pseudo code:

-(IBAction) main {

//Update progress indicator UI to show progress
//perform an call to another object from another class.
// wait till i get its return value.
//Update progress indicator UI to show progress
// Use this return value to do something.
//Update progress indicator UI to show progress


}

当调用另一个对象时,我注意到由于主线程被阻塞,我已经确定的NSProgressIndicator完全消失了.谢谢.

When the call to the other object is made, I notice that the determinate NSProgressIndicator I have completely disappears since the main thread is blocked. Thanks.

推荐答案

您上面的代码不是正确的方法.由于main从不返回,因此进度指示器将永远不会更新.您必须在主线程上快速返回.

Your above code is not the correct approach. Since main never returns, the progress indicator will never update. You must return quickly on the main thread.

相反,您想要做的是设置一个后台块,该块在各个点上都会更新主线程上的进度指示器.因此,例如:

Instead, what you want to do is set up a background block that at various points updates the progress indicator on the main thread. So, for instance:

- (IBAction)start:(id)sender {
  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

  dispatch_async(queue, ^{
    dispatch_async(dispatch_get_main_queue(), ^{[self.progress setProgress:0];});

    // Doing some stuff
    dispatch_async(dispatch_get_main_queue(), ^{[self.progress setProgress:.25];});

    // Doing more stuff
    dispatch_async(dispatch_get_main_queue(), ^{[self.progress setProgress:.75];});
  });
}

(是的,这会导致队列保留self,但这是可以的,因为self没有保留队列.)

(Yes, this causes the queue to retain self, but that's ok here because self is not retaining the queue.)

这篇关于当可可应用中的主线程被阻止时,UI不会更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆