核心数据+AFNetworking+UI更新(响应性)



以下是场景:

我正在编写一个DownloadManager,它允许用户下载、暂停、取消、全部下载和全部暂停。DownloadManager是一个单例,使用AFNetworking下载文件。它有自己的私有托管对象上下文,这样用户就可以自由地使用应用程序的其他部分(通过添加、编辑、删除)核心数据对象。我有一个核心数据实体DownloadInfo,它存储下载信息,即fileURLfileSizebytesRead等。DownloadManager更新DownloadInfo中的下载进度(每个文件一个)。

我有一个DownloadManagerViewController,它使用NSFetchedResultsController向用户显示下载状态。此下载视图控制器正在使用主托管对象上下文。

现在假设我在下载队列中有20个文件。假设只允许3次并发下载。下载管理器应该下载该文件,并显示下载进度。

问题:

CCD_ 12对象正由CCD_ 13以非常高的速率进行更新。DownloadManagerViewController(负责显示下载进度)正在使用NSFetchedResultsControllerDelegate方法更新列表。结果是在主队列中发生了很多事情,应用程序的响应能力非常差。

我该怎么解决这个问题?如何在显示下载进度的同时使应用程序响应?

  1. 我不知道如何在DownloadManagerDownloadManagerViewController之间通信下载状态。还有其他更好的方法吗?

  2. 出于上述原因,我不想在DownloadManager中使用主托管对象上下文。注意,DownloadManager使用的是异步处理请求的AFNetworking,但最终DownloadInfo对象会在主线程中更新(作为回调方法的结果)。也许有一种方法可以在后台线程中处理下载和状态更新操作?但是怎么做呢?我将如何在主线程和后台线程之间进行通信,即我将如何告诉后台线程排队下载另一个文件?

谢谢。

与其观察托管对象上下文的每一次更改,不如考虑为您实际想要更新屏幕的事件实现一个或多个通知。如果通知是从后台线程发布的,请确保在触发任何UI更新之前切换回主线程。

或者,当调用FRC委托方法时,您会收到有关实际更改内容的信息。您可以对此进行分析,筛选出最频繁、最没有意义的更改,并防止它们导致UI更新。

您是否尝试过使用Instruments来查看ViewController中到底发生了什么?时间档案器将告诉您CPU在哪里花费的时间更多,并将帮助您确定问题的根源。如果不知道这一点,我们就无法确切地知道你应该做什么性能调整。

使用Instruments后,如果NSFetchedResultsController强制对VC进行大量更新,则应考虑不要从CoreData中读取进度。我已经看到,我的许多表或视图在读取CoreData时花费的时间比绘制要多。假设您的问题是CoreData读取,我会尝试从NSMutableDictionary读取进度,并在下载超过certan阈值时更新UI。

最新更新