后台线程通知更新NSView

时间:2011-11-10 01:06:58

标签: multithreading cocoa nsnotificationcenter

有一项任务需要在NSView上绘制N个图像。 但是在开始时我不知道图像的数量,因此我将其设置为背景线程。

 [NSThread detachNewThreadSelector:@selector(workInBackgroundThread:) toTarget:self withObject:nil];

当它获得图像数量时,它会发送通知

- (void)workInBackgroundThread:(id)unusedObject {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

//get image amount....

[[NSNotificationCenter defaultCenter] postNotificationName:@"gotImageAmount" object:nil];

//...
//continue to load images

}

我尝试调整NSView的大小取决于通知功能中的图像数量

-(void)processGotImagesAmount:(NSNotification*)notification  
{

    //others codes

    [myNSView setFrame:CGRectMake(0,   0, calculateNewWidth, caculatedNewHeight)];//line A

    //others codes

}

但当应用程序执行A行时,它会冻结,

[myNSView setFrame:CGRectMake(0,   0, calculateNewWidth, caculatedNewHeight)];

本身没有问题,如果我点击一个bottun来调用它,它就可以了!

但看起来它在通知功能中不起作用

欢迎任何评论

1 个答案:

答案 0 :(得分:7)

您正在从后台主题发布通知。

来自NSNotificationCenter文档:

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsnotificationcenter_Class/Reference/Reference.html

  

在多线程应用程序中,始终会传递通知   通知发布的主题

在您的通知处理代码中,您正在更新您必须从主线程执行的操作。尝试将该代码移动到另一个方法,然后在通知处理代码中,使用performSelectorOnMainThread调用它。

另一个选项是没有通知的GCD。我在这个S.O.发布了一个样本。回答:

GCD, Threads, Program Flow and UI Updating