0

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

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

cocoa 究竟需要做什么类似的任务,即允许在单独的线程上进行比 main 更长的操作,然后以某种方式促进更新主线程上的用户界面。

4

2 回答 2

1

您的长期运行的操作应移至 NSOperation 子类

AhmedsOperation.h

@interface AhmedsOperation : NSOperation

@end

AhmedsOperation.m

@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];
}

然后在您的主代码中,当您想要执行操作时,您只需创建一个 AhmedsOperation 对象,并将其推送到 NSOperationQueue 并收听通知。

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]; 
于 2013-02-12T07:01:14.140 回答
0

假设您有一个要更新 UI 的视图控制器的句柄,您可以使用 NSObject " performSelectorOnMainThread:withObject:waitUntilDone:" 方法。

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

dispatch_async(dispatch_get_main_queue(), ^{
    [viewController doSomethingWhenBigOperationIsDone];
}); 

3)或者你甚至可以从你的后台线程发布一个 NSNotification ,观察者(在主线程中)可以更新 UI。

您可能会在这个相关问题中找到一些额外的有用信息

于 2013-02-10T02:12:34.603 回答