Core data 从CoreData加载TableView图像时出现错误且滚动缓慢
问题: 使用存储在核心数据数据库中的图像路径将图像加载到表视图的过程运行良好,但用户体验不太好。卷轴又慢又乱 重要注意事项:Core data 从CoreData加载TableView图像时出现错误且滚动缓慢,core-data,uiimage,tableview,nsurlsession,nsurlsessiondatatask,Core Data,Uiimage,Tableview,Nsurlsession,Nsurlsessiondatatask,问题: 使用存储在核心数据数据库中的图像路径将图像加载到表视图的过程运行良好,但用户体验不太好。卷轴又慢又乱 重要注意事项: 对于我的本地数据库,我使用核心数据 Im不会将图像保存在核心数据中,只保存其路径(图像名称) 对于表视图数据源,我使用Person类型的数组,该数组包含ID和Img名称(TableView rows equal array.Count)。 -这是我从中获取Json的url(请查看)—— 核心数据数据库中的所有对象 据我所知,我在主战场上做了所有的UI更新 每次检查后,我
- 对于我的本地数据库,我使用核心数据
- Im不会将图像保存在核心数据中,只保存其路径(图像名称)
- 对于表视图数据源,我使用Person类型的数组,该数组包含ID和Img名称(TableView rows equal array.Count)。 -这是我从中获取Json的url(请查看)——
- 核心数据数据库中的所有对象
- 据我所知,我在主战场上做了所有的UI更新
- 每次检查后,我都会重新加载tableview
let cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) as UITableViewCelllet photoDetails = photos[indexPath.row]
cell.textLabel.text = photoDetails.name as String
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
var myPathList : NSArray = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true)
var myPath = myPathList[0] as String
myPath = myPath.stringByAppendingPathComponent("\(photoDetails.name).png")
var image : UIImage = UIImage(contentsOfFile: myPath)!
dispatch_async(dispatch_get_main_queue()) {
cell.imageView.image = image
}
}
return cell
有什么建议吗?问题的原因是什么?您不应该总是从磁盘加载映像,它很慢。相反,第一次从磁盘加载映像,然后将其存储在缓存中(内存中)。从磁盘加载映像之前,请检查映像是否已缓存 如果缓存太大或收到内存警告,则需要清空缓存 高级版本可以为当前滚动位置正下方的单元格预缓存一些图像 您可以使用一个库来实现这一点,可能是SDWebImage和文件URL(我还没有尝试过)
错误的部分是因为在加载映像之前,异步块没有检查单元是否已被重用。如果有,则重复使用的单元格上会出现错误的图像(直到被另一个图像替换)。要解决,捕获块中的
indepath
,并在加载图像后获取该indepath
的单元格-如果表视图返回nil
,则该单元格将不再可见,并且您不需要做任何事,只需缓存图像以备将来使用。不清楚显示的代码与表滚动的关系。您不太可能在循环中调用reloadData
。@Wain我将其删除到循环的末尾,仍然会变慢。。有什么建议吗?我已经添加了cellForRowAtIndexPath方法@Wainsounds有趣,你能用我上面的方法支持一个例子吗(试一试,你通过思考和解决问题来学习;-)试了3个小时。。没有结果,我想我发现了问题。每次我滚动它从本地目录重新加载它时,它应该是这样的?这就是为什么我谈论从磁盘加载后的缓存所以你的意思是每次我加载它时都将其移动到nscache?
func CheckIfObjectExistInDBbyID(id : Int32) -> Lockdown? {
let appDelegate =
UIApplication.sharedApplication().delegate as AppDelegate
let managedContext = appDelegate.managedObjectContext!
var request : NSFetchRequest = NSFetchRequest(entityName: "Lockdown")
request.predicate = NSPredicate(format: "id = %d", id)
var error : NSError?
request.fetchLimit = 1
var count : Int = managedContext.countForFetchRequest(request,error: &error)
if count == 0 {
// println("Error : \(error?.localizedDescription)")
println("Object \(id) Dosent exist in CoreData")
return nil
}
println("Object \(id) exist in CoreData")
let result = managedContext.executeFetchRequest(request, error: &error) as NSArray!
let lockdown = result.objectAtIndex(0) as Lockdown
println(lockdown.id)
return lockdown
}
let cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) as UITableViewCelllet photoDetails = photos[indexPath.row]
cell.textLabel.text = photoDetails.name as String
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
var myPathList : NSArray = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true)
var myPath = myPathList[0] as String
myPath = myPath.stringByAppendingPathComponent("\(photoDetails.name).png")
var image : UIImage = UIImage(contentsOfFile: myPath)!
dispatch_async(dispatch_get_main_queue()) {
cell.imageView.image = image
}
}
return cell