执行需要更新屏幕的任务

时间:2011-05-20 01:18:20

标签: iphone

想象一下,我有一个微调器,我必须启用相对较重的东西,然后在任务完成后停用微调器。

如果我这样做:

[mySpinner startAnimating];
[self doSomethingHeavy];
[mySpinner stopAnimating];

我永远不会看到微调器运行,因为doSomethingHeavy将锁定线程并且永远不会让微调器显示。

我试图在主线程上使用Grand Central Dispatch为微调器启动一个新队列,并尝试在另一个尝试中执行该任务,但结果是相同的。没有旋转器运行。

使其工作的唯一方法是使用

延迟激活方法
[self performSelector:@selector(doSomethingHeavy) withObject:nil afterDelay:0.02];

但这听起来更像是黑客,如果我在该行之后放置 [mySpinner stopAnimating] ,它可能会在任务完成之前停止微调器。

这不仅适用于微调器,也适用于需要屏幕更新的任何任务。

3 个答案:

答案 0 :(得分:4)

    ...
    [mySpinner startAnimating];
    [self performSelectorInBackground:@selector(doSomethingHeavy) withObject:nil];
    ...
}


- (void)doSomethingHeavy {
   ...

   [mySpinner performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
}

或者不是在doSomething Heavy中停止微调器,而是更有可能通过调用来完成:

[self performSelectorOnMainThread:@selector(finishedSomethingHeavy) withObject:nil waitUntilDone:NO];

会停止微调器并使用重度结果更新UI。

答案 1 :(得分:0)

希望我能正确理解这个问题,但通常我会使用方法

[self performSelectorInBackground:@selector(doSomethingHeavy) withObject:nil];

在这种情况下,这使主线程可以自由更新UI,同时仍在后台执行任务。

答案 2 :(得分:0)

我尝试过这些解决方案,但不幸的是没有用,因为我的doSomethingHeavy方法也必须在主线程上运行。

使用带有延迟触发方法的hack可以工作但不适用于应该使用多个参数运行的方法,因为performSelector:afterDelay:不能用于传递多个参数。

我找到了一个解决方案,使用Grand Central Dispatch在主线程上触发队列,然后将其休眠0.02秒。使用队列,我可以放任何我想要的东西。