Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 当Cocoa应用程序中的主线程被阻止时,UI不会更新_Objective C_Multithreading_Nsprogressindicator - Fatal编程技术网

Objective c 当Cocoa应用程序中的主线程被阻止时,UI不会更新

Objective c 当Cocoa应用程序中的主线程被阻止时,UI不会更新,objective-c,multithreading,nsprogressindicator,Objective C,Multithreading,Nsprogressindicator,在我运行整个方法时,我在主线程中使用一个NSProgressIndicator来更新进度。现在,当我从另一个类文件调用一个对象,并等待该对象返回到主线程的值时,我注意到NSProgressIndicator将消失。我知道这是因为主线程被阻塞,直到我从另一个对象获得返回值 因此,我的问题是,在主线程中更新UI,而不阻塞UI,让其他对象在后台运行,并根据需要向主线程返回值的建议方法是什么。我知道如何使用块,但块操作不允许返回值。 我需要的是帮助这个伪代码的东西: -(IBAction) main {

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

因此,我的问题是,在主线程中更新UI,而不阻塞UI,让其他对象在后台运行,并根据需要向主线程返回值的建议方法是什么。我知道如何使用块,但块操作不允许返回值。 我需要的是帮助这个伪代码的东西:

-(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完全消失。谢谢。

您可以通过GCD()实现您想要的目标

下面是一个让您开始学习的示例:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
    dispatch_async(queue, ^{
        // Perform async operation
                dispatch_sync(dispatch_get_main_queue(), ^{
                    // Update UI
                });
    });

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

相反,您要做的是设置一个背景块,在不同点更新主线程上的进度指示器。例如:

- (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
没有保留队列。)

听起来您的操作应该在一个单独的线程中运行,该线程可以通过多种方式完成,但使用NSOperationQueue和自定义NSOperation类可能最容易实现(设置它们比听起来容易)或使用NSInvokeOperation类

然后,您可以使用NSNotificationCenter将消息发送回主线程中的类,或者使用键值观察(KVO)将其设置为观察者


总之,你有各种各样的选择,要做出最好的选择,你应该了解底层技术。我会从苹果的个人开始,然后再读一遍,以确保在构建解决方案之前,你已经吸取了所有的优点。

不要在这里调用
dispatch\u release
。这不是你创造的ue所以你不应该发布它。@RobNapier你完全正确。编辑了我的答案,thanx注意到当我添加此代码时,我会出现错误,说找不到我的其他方法定义。有什么想法吗?