将大数据从本地数据库加载到 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:];
所以你的应用程序永远不会冻结并且用户不会感到任何中断,这种情况只有在您的数据是持久的并且具有唯一的行标识符键(主键)时才能实现,而且如果您以升序或降序查询这些数据,对于其他情况,例如,如果您想要任何随机数据,则此答案无效。
另请注意,将代码放入 viewDidAppear
和 UIActivityIndicator
可能是您的解决方案,但如果您要获取更多的行数,那么它会被用户中断。
【讨论】:
【参考方案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 冻结的主要内容,如果未能解决你的问题,请参考以下文章
如何有效地将大数据从数据中心移动到 Azure Blob 存储,以便以后通过 HDInsight 进行处理?