问题: 使用存储在Core Data DB中的路径将图像加载到表视图的过程工作正常,但用户体验不顺利。卷轴很慢而且有错误。
进口商备注:
这是采取正确顺序的步骤:
使用NSURLSession - DataTask获取数据。之后"解析"它并检查Core Data DB中是否存在每个对象(在for循环中),并将其变量附加到TableView数据源数组,然后重新加载数据
1)
let request = NSMutableURLRequest(URL: dataSourceURL!)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
println("error=\(error)")
return
}
if data != nil {
let datasourceDictionary = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as NSDictionary
var DataArray = datasourceDictionary["descisions"] as NSArray
//Convert it to useable array
for var i = 0 ; i < DataArray.count ; i++ {
let ID_s = DataArray[i]["ID"]! as Int
//For each Object from the Json array i'm check if he is exisitng in the local DB
var ConvertetdID = Int32(ID_s)
let object : Lockdown? = self.CheckIfObjectExistInDBbyID(ConvertetdID)
//CheckIfExists - if it does , it return an object with the correct values
if object != nil {
//exists - load file from Core Data
let imgname = object!.imgPath
let photoRecord = PhotoRecord(name:"\(ConvertetdID)", url:imgname)
self.photos.append(photoRecord)
//TableView object array (photos)
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
//After each check reload the tableView
}
}
}
}
task.resume()
检查Core Data DB中是否存在的方法(该方法接收ID并返回对象(如果存在),否则返回nil:
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
}
cellForRowAtIndexPath方法
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
有什么建议是什么原因造成的?
答案 0 :(得分:0)
您不应该总是从磁盘加载图像,它很慢。而是首次从磁盘加载映像,然后将其存储在缓存中(在内存中)。在从磁盘加载图像之前检查图像是否被缓存。
如果缓存太大或者出现内存警告,则需要清空缓存。
高级版本可以为当前滚动位置正下方的单元格预先缓存一些图像。
你可能可以使用一个库,也许是带有文件URL的SDWebImage(我没试过这个)。
错误部分是因为您的异步块在加载图像之前未检查该单元格是否未被重用。如果有,那么错误的图像将出现在重用的单元格上(直到它被另一个图像替换)。要修复,请捕获块中的indexPath
,并在加载图像后获取indexPath
的单元格 - 如果表格视图返回nil
,则单元格不再可见除了缓存图像以备将来使用外,还需要做任何其他事情。