在我的应用程序中,当我按下按钮时,我想要更新我的数据库。因为这项工作需要一些时间而不是冻结漏洞应用我决定使用NSThread。
此过程可以从不同的视图开始,因此我将更新代码放在我的App Delegate中。按下更新方法时,我有以下代码:
MyAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[NSThread detachNewThreadSelector:@selector(startTheBackgroundJob) toTarget:delegate withObject:nil];
在我的代表中:
- (void)startTheBackgroundJob {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//do some stuff here
self.percentageCompleted = (i * 100) / totalChars;
[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshObjectsForUpdate" object:self];
//some other stuff
[pool release];
基本上在我的线程中我想用当前进度更新不同的progressView。所以我使用NSNotificationCenter在我的线程的每一步之后发送消息。
在viewController中,我正在捕捉此消息,我正在做:
MyAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
double prc = delegate.percentageCompleted;
UILabel *l = (UILabel *)[self.view viewWithTag:444];
l.text = [NSString stringWithFormat:@"%f", prc];
但它只在帖子的末尾刷新我的标签。
这是什么问题?我可以用另一种方法吗?
感谢。
答案 0 :(得分:4)
在多线程应用程序中,通知始终在发布通知的线程中传递...
因此您需要执行代码以在主线程上明确更新UI(使用performSelectorOnMainThread:withObject:waitUntilDone:
或任何合适的内容)。
答案 1 :(得分:2)
@paulbailey关于在主线程上执行选择器是正确的。我还要补充一点,如果你正在做的是高性能,我会完全避免使用通知中心。它将同步广播,这意味着每个循环迭代都会更新每个UI元素。您可以在performSelector方法上使用“waitUntilDone”标志使其异步,但是您可能会导致许多线程和上下文切换。
看看NSNotificationQueue并合并面具。您可以按照自己喜欢的方式发布,并且只会将通知合并到可以方便地发送它们。这当然具有较低的交付保证,因此您需要检查它是否会导致您的UI无法接受。