如何更改此代码才能正常工作?

时间:2010-10-07 06:36:18

标签: objective-c multithreading cocoa-touch selector nsthread

我从http://github.com/matej/MBProgressHUD下载了一些代码,以便在执行操作时显示进度表。

这是使进度表弹出的代码。

[HUD showWhileExecuting:@selector(myTask) onTarget:self withObject:nil animated:YES];

这将在myTask运行方法时显示进度表。

奇怪的是,当myTask运行时,它还允许程序执行继续低于此行。这不是我想要的行为。我希望在myTask运行时显示进度表,并且只有在myTask完成运行后才能让程序执行继续在此行之下。

这是showWhileExecuting方法的代码。

- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated {

    methodForExecution = method;
    targetForExecution = [target retain];
    objectForExecution = [object retain];

    // Launch execution in new thread
 taskInProgress = YES;
    [NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil];

 // Show HUD view
 [self show:animated];
}

为了获得我想要的行为,我应该编辑这段代码还是做其他的事情?

我尝试通过在调用此方法之前设置bool值来解决此问题,这会导致程序执行在myTask结束时更改bool值后立即停留在while循环中。这是有效的,但由于某种原因,它导致仪表只在最后出现,而不是像它应该的那样。那是为什么?

2 个答案:

答案 0 :(得分:1)

您正在调用的方法是在新线程上运行您的任务。

您的while循环方法无效,因为UI显示更新是在主线程上完成的。当你在while循环中时,你阻止主线程。

我建议您在任务完成后将要运行的代码移动到新方法。然后,在任务结束时,调用此方法。 (或者,让它发送通知或其他信号。)

另外,查看有关线程和运行循环的文档,了解此主题非常重要。

答案 1 :(得分:1)

这是因为你从根本上误解了在iOS中绘制视图的方式。

当视图状态发生变化时,状态变化所带来的效果不会立即显示在屏幕上。真正发生的是,将要更改的视图标记为无效,并放置在需要重绘的事物的队列中。然后,当当前事件的处理完成时,将处理所有排队的更改。

因此,在您的while循环到位后,HUD视图将仅在您的线程任务完成时显示。当然,在那时,是时候停止显示视图了。

您需要做的是将要延迟的处理移动到线程完成自己的方法之后。然后,在线程结束时,您可以使用-performSelectorOnMainThread:...来启动剩余的处理。

如果您想要禁用用户界面元素,则需要一些额外的状态,以便他们知道它们已被禁用。