我正在开发一个带有 UITableView 的 iOS 应用程序,它在某个阶段添加或删除了一堆行。由于存在大量行,因此此操作可能需要很长时间。但是,我不能轻易确定它是否需要很长时间。
仅当此操作需要很长时间时,我才想显示 UIActivityIndicator (微调器)。我一直这样做的方式是启动冗长的操作,经过一些延迟(比如 0.5 秒)后,我们测试操作是否仍在运行,如果是,我们开始显示 UIActivityIndicator。
如果您可以在后台线程中运行冗长的操作,这没有问题。但是,这种特殊情况很棘手,因为冗长的操作 (deleteRowsAtIndexPaths:withRowAnimation:) 必须在主线程中运行(如果我在后台线程中运行此方法,当后台线程尝试更新 UI 时,应用程序偶尔会崩溃)。
我尝试过的最新事情是这样的:
- (void) manipulateTableView
{
stillBusy = YES;
[self performSelectorInBackground:@selector(waitBeforeShowingBusyIndicatorForView:) withObject:view];
.
.
.
[self performSelectorOnMainThread:@selector(deleteRowsAtIndexPathsWithRowAnimation:) withObject:args waitUntilDone:YES];
stillBusy = NO;
}
- (void) waitBeforeShowingBusyIndicatorForView:(UIView*) view
{
usleep((int) (BUSY_INDICATOR_DELAY * 1000000));
if (stillBusy)
[self performSelectorOnMainThread:@selector(showBusyIndicatorForView:) withObject:view waitUntilDone:NO];
}
因为 showBusyIndicatorForView: 操作 UI,所以必须在主线程调用,否则应用可能会崩溃。
当 deleteRowsAtIndexPaths:withRowAnimation: 耗时很长时,waitBeforeShowingBusyIndicatorForView: 中的延迟到期,调用 performSelectorOnMainThread:... 方法并立即返回。但是只有在对 deleteRowsAtIndexPaths:withRowAnimation: 的调用完成后才调用 showBusyIndicatorForView: 方法,这违背了目的。
我想我明白为什么会发生这种情况。deleteRowsAtIndexPaths:withRowAnimation: 方法在主循环的迭代中运行,当它运行时,对 showBusyIndicatorForView: 的调用作为主循环的消息排队。只有在主循环完成执行 deleteRowsAtIndexPaths:withRowsAnimation: 后,它才会轮询队列以获取下一条消息,然后开始执行 showBusyIndicatorForView:。
有没有办法让这个东西正常工作。是否有可能中断主循环并使其立即执行 showBusyIndicatorForView: ?