使用UITableView锁定RunLoop

时间:2011-12-14 20:53:50

标签: iphone ios ipad

我正在编写一个iPad应用程序并且在ui响应/锁定方面存在问题。

我有一个带有项目的 UITableView ,当点击一个项目时,它会在互联网上显示并提取该项目并显示它。程序的其余部分(未显示)将使用下载的项目,因此一次只能下载一个项目。

获取该项目可能需要很长时间。在此期间,我希望用户仍然可以在UITableView上滚动,但是在点击上一个项目之前无法选择任何内容。

我知道这可以使用线程,块和回调来完成,但是现在我没有时间这样做(不可能的时间限制)。

我认为快速的方法是按顺序下载它并使用run循环和一个标志,就像这两个步骤:

  1. 当用户点击表格单元格调用didSelectRowAtIndexPath时,我在那里设置了一个全局标志,然后调用下载方法下载该项目。如果用户点击另一个项目(在下载完成之前,它将看到标志被检查并退出该功能而不下载任何内容。基本上这个:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        static BOOL alreadyInHere=FALSE;
        if (alreadyInHere) return;
        alreadyInHere=TRUE;
        ....
        downloadItem(...);
        ShowAndUseItem(...);
        alreadyInHere=FALSE;
    }
    

    这允许用户一次只选择一个项目。

  2. 为了让用户能够在长时间下载期间仍然在UITableView上滚动,我在上面显示的downloadItem(...)方法中输入了一个运行循环,就像这样......

    -(void) downloadItem(....)
    {
        BOOL downloading=TRUE;
        callFunctionsToStartdownload(...); //
        while (downloading) {
            downloading=DownloadSomeBytes(...);  
            CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.5, YES);
        }
    }
    
  3. (1)和(2)的结果是用户仍然可以在顺序下载期间滚动UITableView,而yetInHere标志阻止他们选择某些东西并开始另一次下载。

    这在大多数情况下有效,但是大约50%的时间,在下载过程中,UITableView变得没有响应(无法滚动到表格中的其他项目),甚至在下载之后,当你再也没有调用doSelectRowAtIndexPath时点击使得UITableView基本上被锁定的东西。

    我的问题是,我是否正确执行了runLoop?

    我知道还有其他方法可以做到这一点,但由于其他原因,我现在必须使用这种通用方法。

    由于

1 个答案:

答案 0 :(得分:1)

您不应该尝试在youR tableview didSelectRow方法中下载或执行任何其他可能很长的活动。在设置异步下载后,从此UI方法退出(返回),以便您不会锁定UI。

锁定同步下载仍然可以,但您需要小心在错误或超时后重置状态。