将大数据从本地数据库加载到 UITableview 而无需 ui 冻结

Posted

技术标签:

【中文标题】将大数据从本地数据库加载到 UITableview 而无需 ui 冻结【英文标题】:Loading Large data to UITableview from local database without ui freeze 【发布时间】:2012-10-22 10:12:27 【问题描述】:

我正在从 Ultralite 数据库中检索 10,000 条记录到一个数组中。

我的查询需要 3 秒的时间将值加载到数组中。每当我单击打开视图控制器时,这会使 UI 冻结 3 秒。

我想在后台执行查询时立即打开视图控制器并显示 Activity 指示器 3 秒。

如果可能的话,我想动态显示行动画并显示行数,例如“检索到的产品数为 5045”。

请问,谁能帮我解决这个问题?

提前致谢。

编辑:

NSMutableArray *customerArray = [[DB sharedInstance] LoadCustomerOverview];

“LoadCustomerOverview”是一个函数,它具有从 Ultrlite 数据库中检索 10,000 条记录的 select 语句。

以上行需要 3 秒。我在上述声明之前和之后用NSLog 进行了检查。使用这个“customerArray”我将在我的视图控制器中填充UITableview,它只需要毫秒来准备单元格。

问题出在上面一行。

我该如何解决这个问题?或任何其他提高性能的方法?

提前致谢。

【问题讨论】:

请给我们看代码...... 对于大数据数组,可以尝试新建一个容量为:[NSMutableArray arrayWithCapacity:10000];然后分配数据。 【参考方案1】:

接受所有其他好的答案,这可能略有不同,iPhone 设备有(大部分)10-11,iPad 设备有两倍(我不知道),@987654321 中用户可见的行数@。如果您真的不需要一次处理或显示所有 10k 条记录,我认为您真的不需要查询所有记录,因为您提出的问题需要良好的内存和处理时间。相反,您可以一次获取(查询)1k(甚至少量)记录,一旦您获得 1k(或您想要的数量),您就可以查询下一条记录,这应该在 [self performSelectorInBackground:@selector(getRecordsFromDatabase) withObject:]; 所以你的应用程序永远不会冻结并且用户不会感到任何中断,这种情况只有在您的数据是持久的并且具有唯一的行标识符键(主键)时才能实现,而且如果您以升序或降序查询这些数据,对于其他情况,例如,如果您想要任何随机数据,则此答案无效。

另请注意,将代码放入 viewDidAppearUIActivityIndicator 可能是您的解决方案,但如果您要获取更多的行数,那么它会被用户中断。

【讨论】:

【参考方案2】:

我无法想象你为什么需要 10000 条记录在一个数组中,因为这可能是可以优化的。

但是,要回答您的问题,您可以将加载方法移至 viewDidAppear:(我假设您正在 viewDidLoad:) 中进行获取,并在开始加载之前显示某种进度条。

【讨论】:

【参考方案3】:
[NSThread detachNewThreadSelector:@selector(startBackgroundProcess:) toTarget:self withObject:YOUR_OBJECT];

-(void)startBackgroundProcess:(id)obj
//interact with DB..
//After firing the query and get the Data 
[self performSelectorOnMainThread:@selector(finishedBackgroundProcess:) withObject:YOUR_RESULT waitUntilDone:NO];  

【讨论】:

您好,我没有得到“withObject”的概念。你能解释一下吗? withObject 表示您将在finishedBackgroundProcess 方法中作为参数传递的内容【参考方案4】:

解决方案是 performSelectorInBackground,它不会冻结你的 UI

[self performSelectorInBackground:@selector(getRecordsFromDatabase) withObject:yourObjectHereAsArgument]

现在方法:

-(void)getRecordsFromDatabase

  //retrieve records here

【讨论】:

【参考方案5】:

更新:你使用 Core Data 吗? 如果你批处理怎么办? [fetchRequest setFetchBatchSize:20];

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSFetchRequest_Class/NSFetchRequest.html

问候,

【讨论】:

我听说 Core Data 只兼容 SQLite,不兼容 Ultralite。所以我没有尝试核心数据。我现在正在使用 KVC 将您的 db 转换为 coredata 不是更好吗?使用核心数据可以大大减少你的 sql 代码。 它与 uikit 完美集成 - 所以使用 uitable 会更容易 可以,但核心数据与 Sybase Ultralite DB 不兼容 :(

以上是关于将大数据从本地数据库加载到 UITableview 而无需 ui 冻结的主要内容,如果未能解决你的问题,请参考以下文章

将大数据从 sql server 下载到 iOS [关闭]

如何将大文件存储到 Web 本地存储?

UITableView 本地图片的快速加载

如何有效地将大数据从数据中心移动到 Azure Blob 存储,以便以后通过 HDInsight 进行处理?

将大数据集加载到 Java 中的 ArrayList(ArrayList 的最大容量)

将大 csv 文件中的小随机样本加载到 R 数据框中