代码之家  ›  专栏  ›  技术社区  ›  Anurag

核心数据、文件下载和线程安全

  •  2
  • Anurag  · 技术社区  · 15 年前

    在使用核心数据时,在线程间持续共享数据的首选方法是什么?我正在下载一个大文件,希望在 UIProgressBar . 实际下载发生在由创建的后台线程中 NSOperation .

    下载信息(本地路径、总字节数、接收的字节数)被建模为核心数据管理对象,实际文件存储在文档/目录中。我想到的一个解决方案是在后台线程中创建一个单独的托管对象上下文,并将其传递给 objectID 然后用 objectWithID: 方法。每当后台线程执行保存操作时,主线程将收到通知,主上下文将合并这些更改,然后更新表视图。

    这种方法是可行的,但是保存不能太频繁,否则UI会冻结。因此,在接收到每x kb的数据后,用户界面都会更新,其中x必须至少为500 kb才能使用户界面有一定的响应性。是否有更好的方法在接收到下载进度数据时将其传递给主线程?

    编辑:使用kvo有什么帮助吗?如果是,你知道关于这个主题的任何好的教程吗?

    2 回复  |  直到 15 年前
        1
  •  4
  •   coneybeare    15 年前

    我知道你已经建立了自己的系统,但是我用 ASIHTTPRequest 我所有的网络操作。它非常健壮,有很多优点,如文件恢复、直接保存到磁盘、上传进度监控、下载进度监控和厨房水槽。如果您不使用它,您可以查看源代码以了解它们是如何做到的,因为当我在这个框架中使用进度报告时,UI永远不会冻结。

        2
  •  0
  •   Anurag    15 年前

    尽管我将在我的项目中使用AsihtpRequest,但为了完整性,最好还是提到我的问题解决方案。这是显而易见的,但是每隔几秒钟就保存核心数据上下文是一个严重的错误。

    相反,我向下载操作添加了一个进度委托,它在主线程上得到更新通知。

    NSNumber bytesDownloaded = [NSNumber numberWithLongLong:[data length]];
    [downloadDelegate performSelectorOnMainThread:@selector(updateProgress:) withObject:bytesDownloaded waitUntilDone:NO];
    

    重要的是将下载进度信息传递给主线程上的代理。代理会更新进度,不断累积更改,并在下载完成时保存更改,或者以更大的间隔保存更改。