我必须做一个可能需要很长时间才能完成的IO操作。通过按钮调用IO操作。 当然,UI挂起,直到操作完成。所以我想我需要在某些后台线程上执行IO,但是当操作完成时,我必须更新窗口的标签以指示操作完成。我想我应该在主线程上做什么(比如java中的EDT和C#中的类似),对吗?
在C#中有类似TaskAsync的类,在Java android中类似。这让你可以在另一个线程中完成长任务,当任务完成时,在主线程上调用一个处理程序,以便可以在主线程上更新UI,
cocoa究竟要做什么类似的任务,即允许在单独的线程上进行长操作而不是main,然后以某种方式有助于更新主线程上的用户界面。
答案 0 :(得分: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];
答案 1 :(得分:0)
假设您有一个想要更新UI的视图控制器的句柄,您可以使用NSObject“performSelectorOnMainThread:withObject:waitUntilDone:
”方法。
2)你也可以使用这样的代码来使用Grand Central Dispatch:
dispatch_async(dispatch_get_main_queue(), ^{
[viewController doSomethingWhenBigOperationIsDone];
});
3) 或者您甚至可以从后台线程发布NSNotification,其中观察者(在主线程中)可以更新UI。
You might find some additional useful information in this related question