Objective c 如何在后台线程上执行长操作,然后在主线程上更新UI

Objective c 如何在后台线程上执行长操作,然后在主线程上更新UI,objective-c,macos,cocoa,Objective C,Macos,Cocoa,我必须执行IO操作,这可能需要很长时间才能完成。IO操作通过按钮调用。 当然,UI会一直挂起,直到操作完成。所以我想我需要在一些后台线程上执行IO,但是当操作完成时,我必须更新窗口的标签来表示操作完成。我想我应该在主线程上做这件事(像java中的EDT和C#中的类似),对吗 在C#中有类似TaskAsync的类,在Java android中也有类似的类。它允许您在另一个线程中完成长任务,并且当任务完成时,将在主线程上调用处理程序,以便在主线程上更新UI cocoa到底需要做什么来完成类似的任务,

我必须执行IO操作,这可能需要很长时间才能完成。IO操作通过按钮调用。 当然,UI会一直挂起,直到操作完成。所以我想我需要在一些后台线程上执行IO,但是当操作完成时,我必须更新窗口的标签来表示操作完成。我想我应该在主线程上做这件事(像java中的EDT和C#中的类似),对吗

在C#中有类似TaskAsync的类,在Java android中也有类似的类。它允许您在另一个线程中完成长任务,并且当任务完成时,将在主线程上调用处理程序,以便在主线程上更新UI


cocoa到底需要做什么来完成类似的任务,即允许在独立于主线程的线程上执行长时间的操作,然后以某种方式帮助更新主线程上的用户界面

假设您拥有要更新UI的视图控制器的句柄,则可以使用NSObject“”方法

2) 您还可以使用如下代码的Grand Central Dispatch:

dispatch_async(dispatch_get_main_queue(), ^{
    [viewController doSomethingWhenBigOperationIsDone];
}); 
(三) 或者,您甚至可以从后台线程发布一个通知,让观测者(在主线程中)更新UI


.

长时间运行的操作应移动到NSOperation子类

艾哈迈德

@interface AhmedsOperation : NSOperation

@end
艾哈迈德

@implementation AhmedsOperation

// You override - (void)main to do your work
- (void)main
{
    for (int i = 0; i < 1000; i++) {
        if ([self isCancelled]) {
            // Something cancelled the operation
            return;
        }

        sleep(5);

        // Emit a notification on the main thread
        // Without this, the notification will be sent on the secondary thread that we're
        // running this operation on
        [self performSelectorOnMainThread:@(sendNotificationOnMainThread:)
                               withObject:[NSNotification notificationWithName:@"MyNotification"
                                                                        object:self
                                                                      userInfo:nil]
                            waitUntilDone:NO];
    }
}

- (void)sendNotificationOnMainThread:(NSNotification *)note
{
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc postNotification:note];
}

嵌套调度将是cocoa的等价物,但如果您正在寻找更类似C#的东西,请使用ReactiveCocoa的-deliverOn:@CodaFi很抱歉,我不了解嵌套调度,我对cocoa非常陌生。精化将有助于方法1,如果我理解正确,我必须手动启动一个新线程(可能是NSThread?correct?),当线程结束时,我可以从该线程调用所提到的函数,基本上在主线程上发布/执行代码?请原谅,我对objective-c/cocoaNo完全陌生。如果您已经启动了一个后台线程来执行长时间的操作,那么您只需将结果报告给主线程中正在更新UI的用户(可能与启动后台线程的主线程相同)。我还没有创建任何后台线程,只有主线程在执行长IO。但我想我理解你的建议。感谢您的帮助:)对于3)您需要小心,因为每个线程都有一个单独的NSNotificationCenter,因此您需要让您的后台线程在主线程上发布通知。
AhmedsOperation *op = [[AhmedsOperation alloc] init];
NSOperationQueue *defaultQueue = [MLNSample defaultOperationQueue];

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
       selector:@selector(progressUpdateNotification:)
           name:@"MyNotification"
         object:op];

[defaultQueue addOperation:op];