我正在编写一个iPad应用程序并且在ui响应/锁定方面存在问题。
我有一个带有项目的 UITableView ,当点击一个项目时,它会在互联网上显示并提取该项目并显示它。程序的其余部分(未显示)将使用下载的项目,因此一次只能下载一个项目。
获取该项目可能需要很长时间。在此期间,我希望用户仍然可以在UITableView上滚动,但是在点击上一个项目之前无法选择任何内容。
我知道这可以使用线程,块和回调来完成,但是现在我没有时间这样做(不可能的时间限制)。
我认为快速的方法是按顺序下载它并使用run循环和一个标志,就像这两个步骤:
当用户点击表格单元格调用didSelectRowAtIndexPath时,我在那里设置了一个全局标志,然后调用下载方法下载该项目。如果用户点击另一个项目(在下载完成之前,它将看到标志被检查并退出该功能而不下载任何内容。基本上这个:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
static BOOL alreadyInHere=FALSE;
if (alreadyInHere) return;
alreadyInHere=TRUE;
....
downloadItem(...);
ShowAndUseItem(...);
alreadyInHere=FALSE;
}
这允许用户一次只选择一个项目。
为了让用户能够在长时间下载期间仍然在UITableView上滚动,我在上面显示的downloadItem(...)方法中输入了一个运行循环,就像这样......
-(void) downloadItem(....)
{
BOOL downloading=TRUE;
callFunctionsToStartdownload(...); //
while (downloading) {
downloading=DownloadSomeBytes(...);
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.5, YES);
}
}
(1)和(2)的结果是用户仍然可以在顺序下载期间滚动UITableView,而yetInHere标志阻止他们选择某些东西并开始另一次下载。
这在大多数情况下有效,但是大约50%的时间,在下载过程中,UITableView变得没有响应(无法滚动到表格中的其他项目),甚至在下载之后,当你再也没有调用doSelectRowAtIndexPath时点击使得UITableView基本上被锁定的东西。
我的问题是,我是否正确执行了runLoop?
我知道还有其他方法可以做到这一点,但由于其他原因,我现在必须使用这种通用方法。
由于
答案 0 :(得分:1)
您不应该尝试在youR tableview didSelectRow方法中下载或执行任何其他可能很长的活动。在设置异步下载后,从此UI方法退出(返回),以便您不会锁定UI。
锁定同步下载仍然可以,但您需要小心在错误或超时后重置状态。