想象一下,我有一个微调器,我必须启用相对较重的东西,然后在任务完成后停用微调器。
如果我这样做:
[mySpinner startAnimating];
[self doSomethingHeavy];
[mySpinner stopAnimating];
我永远不会看到微调器运行,因为doSomethingHeavy将锁定线程并且永远不会让微调器显示。
我试图在主线程上使用Grand Central Dispatch为微调器启动一个新队列,并尝试在另一个尝试中执行该任务,但结果是相同的。没有旋转器运行。
使其工作的唯一方法是使用
延迟激活方法[self performSelector:@selector(doSomethingHeavy) withObject:nil afterDelay:0.02];
但这听起来更像是黑客,如果我在该行之后放置 [mySpinner stopAnimating] ,它可能会在任务完成之前停止微调器。
这不仅适用于微调器,也适用于需要屏幕更新的任何任务。
答案 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秒。使用队列,我可以放任何我想要的东西。