后台线程通知更新NSView

mon*_*bre 1 cocoa multithreading nsnotificationcenter

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

 [NSThread detachNewThreadSelector:@selector(workInBackgroundThread:) toTarget:self withObject:nil];
Run Code Online (Sandbox Code Playgroud)

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

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

//get image amount....

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

//...
//continue to load images

}
Run Code Online (Sandbox Code Playgroud)

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

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

    //others codes

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

    //others codes

}
Run Code Online (Sandbox Code Playgroud)

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

[myNSView setFrame:CGRectMake(0,   0, calculateNewWidth, caculatedNewHeight)];
Run Code Online (Sandbox Code Playgroud)

本身没有问题,如果我点击一个bottun来调用它,它的工作原理!

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

欢迎任何评论

bry*_*mac 7

您正在从后台线程发布通知.

来自NSNotificationCenter文档:

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

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

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

另一种选择是没有通知的GCD.我在这个SO答案中发布了一个样本:

GCD,线程,程序流和UI更新