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

标签 objective-c macos cocoa

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

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

cocoa 到底要做什么类似的任务,即允许在与主线程不同的单独线程上进行长时间操作,然后以某种方式促进更新主线程上的用户界面。

最佳答案

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

艾哈迈德操作.h

@interface AhmedsOperation : NSOperation

@end

艾哈迈德操作.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]; 

关于objective-c - 如何在后台线程上执行长时间操作,然后在主线程上更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14793907/

相关文章:

objective-c - 如何在Objective-C中将字节数组转换为图像

mysql - -bash : ./配置 : No such file or directory - MySQL install on Mac OS X 10. 6

Objective-C 扩展在某些情况下生成 "may not respond warning"

xcode - 更改 CLLocationManager 的文本允许 OS X 上的权限警报

ios - NSMutableArray 在 NSLog 中显示 "(" ")"普通括号而不是 "[" "]"方括号

objective-c - 更改 UITextField 中光标的颜色

c++ - 为 iPhone 应用程序解析 RSS/Atom 提要的最佳方法是什么?

ios - 未从App Store下载时如何更新XCode

xcode - 在界面生成器中拖动 Canvas

objective-c - 在其他 View 上显示 NSView 子类