UI 挂起,直到完成所有提取
Posted
技术标签:
【中文标题】UI 挂起,直到完成所有提取【英文标题】:UI hangs until all fetches are done 【发布时间】:2016-07-14 15:52:03 【问题描述】:我有这段代码来搜索不同的表,我的问题是在执行 las fetch 请求之前我无法与 UI 交互。 如果我搜索特定值并且结果在“Table2”中,tableView 更新正常,但在完成搜索最后一个表之前无法与之交互。 func loadData() 只需要几毫秒即可执行和退出,并且获取正在不同的线程中执行。我不知道这段代码有什么问题,有什么帮助或建议吗? 所有表中的记录总数约为 500 万条,搜索所有记录需要一些时间,这就是为什么我不想让用户在完成搜索整个数据库之前如果有一些结果可用就让用户等待。
func loadData ()
let tablas = ["Table1", "Table2", "Table3", "Table4", "Table5", "Table6", "Table7", "Table8", "Table9", "Table10", "Table11"]
let managedContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
managedContext.parentContext = self.moc
for tbl in tablas
managedContext.performBlock
let fetchRequest = NSFetchRequest(entityName: tbl)
let predicate = NSPredicate(format: "name CONTAINS %@", self.filter)
fetchRequest.predicate = predicate
fetchRequest.resultType = NSFetchRequestResultType.ManagedObjectIDResultType
fetchRequest.fetchLimit = 50
fetchRequest.fetchBatchSize = 10
do
let results = try managedContext.executeFetchRequest(fetchRequest) as! [NSManagedObjectID]
if results.count != 0
self.resultArray.appendContentsOf(results)
dispatch_async(dispatch_get_main_queue())
self.tableView.reloadData()
catch let error as NSError
dispatch_async(dispatch_get_main_queue())
let errorAlert = UIAlertController(title: "Error!!!", message: error.localizedDescription, preferredStyle: .Alert)
errorAlert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
self.presentViewController(errorAlert, animated: true, completion: nil)
【问题讨论】:
为什么不先加载 5-10 条内容,然后实现拉取刷新并添加 5-10 条新记录。 大多数搜索的结果少于 10 个,我不想要求用户刷新并等待加载 2 条或可能 0 条记录。 然后使用 dispatch_async(dispatch_get_main_queue(), ) 【参考方案1】:这里有一些链接可帮助您规划代码
UITableView Load Data from JSON
Refreshing uitableview asynchronously after Core Data loaded
25 ios app performance tips tricks (Ray Wenderlich)
【讨论】:
尝试了异步获取,但 tableview 在完成对所有表的搜索后刷新。【参考方案2】:UI 在主线程中处理其大部分进程。如果您有一个主要进程,请不要在主线程上同步运行它。您可以在主线程上异步运行它。
在主线程上异步运行的代码:
dispatch_async(dispatch_get_main_queue(),
// RUN CODE OVER HERE
)
【讨论】:
我的主要过程是获取并在不同的线程中运行(“managedContext.performBlock”),您提供给我的代码是访问主线程并更新 UI。以上是关于UI 挂起,直到完成所有提取的主要内容,如果未能解决你的问题,请参考以下文章
使用 Jenkins 从共享文件夹上的存储库中提取时 Git 挂起
ContentProvider insert() 总是在 UI 线程上运行?