NSOperation阻止UI绘画? [英] NSOperation blocks UI painting?

查看:131
本文介绍了NSOperation阻止UI绘画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对一些建议使用 NSOperation 和绘图:

I'm after some advice on the use of NSOperation and drawing:

我有一个主线程创建我的 NSOperation 子类,然后将其添加到 NSOperationQueue

I have a main thread create my NSOperation subclass, which then adds it to an NSOperationQueue.

我的 NSOperation 做一些重的处理,它的目的是循环其main()方法几分钟,不断地处理一些工作,但现在我只是一个while()循环,里面有一个sleep(1),设置为只有5次(用于测试)。

My NSOperation does some heavy processing, it is intended to loop in its main() method for several minutes, constantly processing some work, but for now I just have a while() loop with a sleep(1) inside, which is set to go around just 5 times (for testing).

这个 NSOperation 负责绘制视图并更新UI。

The main (original) thread which spawns this NSOperation is responsible for drawing to a view and updating the UI.

我打算让NSOperation线程使用一个通知告诉主线程它已经做了一些量的处理,在这一刻每当它通过其while()循环发送一次这个通知(即;每秒一次,因为它只是做睡眠(1)) 。主线程(视图),注册接收这些通知。

I intended to have the NSOperation thread use a notification to tell the main thread that it had done some amount of processing, at the moment this notification is sent once each time it goes through its while() loop (that is; once a second because it's just doing sleep(1)). The main thread (the view), registers to receive these notifications.

通知立即通过主线程,看起来是异步的,看起来很好。看起来两个线程都按预期运行...这是并发的。 (我使用NSLog()只是粗略检查每个线程发送和接收通知)。

The notifications get through to the main thread immediately, and seeming asynchronously, looking just fine. It appears that both threads run as expected... that is - concurrently. (I use NSLog() just to check roughly when each thread sends and receives the notification).

当视图接收到一个通知,只需增加一个整数变量,并尝试并绘制到视图(当然是一个字符串)。在测试中,drawRect中的代码将这个整数(作为字符串)绘制到屏幕上。

When the view receives a notification, and its handler method is called, I simply increment an integer variable, and try and draw this to the view (as a string of course). In testing, the code in drawRect: draws this integer (as a string) to the screen just fine.

但是:这里是我的问题在这里):当主线程(视图)收到来自NSOperation的通知,它更新这个测试整数并调用[self setNeedsDisplay]。但是,视图不重新绘制自己,直到NSOperation完成!我预计NSOperation作为一个单独的线程,将无法阻塞主线程的事件循环,但似乎这是发生了什么。当NSOperation完成并且它的main()返回时,视图最终立即重新绘制。

However: here's my problem (sorry it's taken a little while to get here): when the main thread (view) receives a notification from the NSOperation, it updates this test integer and calls [self setNeedsDisplay]. However, the view does not redraw itself until the NSOperation is finished! I expected that the NSOperation, being a separate thread, would have no ability to block the main thread's event loop, but it appears that this is what is happening. When the NSOperation finishes and its main() returns, the view finally redraws itself straight away.

也许我不使用 NSOperation 正确。我使用它在非并发模式,但尽管我的理解是,这仍然产生一个新的线程并允许异步处理。

Perhaps I am not using NSOperation correctly. I am using it in "non- concurrent" mode, but despite the name my understanding is that this still produces a new thread and allows for asynchronous processing.

任何帮助或

推荐答案

在观察者中的方法是

因此,在该方法中,您可以强制另一个方法在主线程上使用 performSelectorOnMainThread:withObject:waitUntilDone:

So, in that method, you can force another method to run on the main thread using performSelectorOnMainThread:withObject:waitUntilDone:.

例如:

MyOperation.m

MyOperation.m

- (void)main {
    for (int i = 1; i <= 5; i++) {
        sleep(1);
        [[NSNotificationCenter defaultCenter] postNotificationName:@"GTCNotification" object:[NSNumber numberWithInteger:i]];
    }
}

MyViewController.m / p>

MyViewController.m

- (void)setupOperation {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myNotificationResponse:) name:@"GTCNotification" object:nil];

    NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
    MyOperation *myOp = [[MyOperation alloc] init];

    [opQueue addOperation:myOp];

    [myOp release];
    [opQueue release];
}

- (void)myNotificationResponse:(NSNotification*)note {
    NSNumber *count = [note object];
    [self performSelectorOnMainThread:@selector(updateView:) withObject:count waitUntilDone:YES];
}

- (void)updateView:(NSNumber*)count {
    countLabel.text = count.stringValue;
}

这篇关于NSOperation阻止UI绘画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆