1

问题: 使用存储在 Core Data DB 中的路径将图像加载到表视图的过程工作正常,但用户体验不佳。卷轴很慢而且有问题。

重要提示:

  • 对于我的本地数据库,我使用核心数据
  • 我没有将图像保存在 Core Data 中,只有它们的路径(图像名称)
  • 至于表视图 DataSource ,我使用 Person 类型的数组,其中包含 ID 和 Img 名称(TableView 行等于 array.Count)。- 这是获取我的 Json 的网址(查看) - Json Link
  • Core Data DB 中的所有对象
  • 据我所知,我在 Main theard 完成了所有 UI 更新
  • 每次检查后,我都会重新加载 tableview。

这是按照正确顺序采取的步骤:

使用 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

任何建议问题的原因是什么?

4

1 回答 1

0

您不应该总是从磁盘加载图像,它很慢。相反,第一次从磁盘加载图像,然后将其存储在缓存中(在内存中)。在从磁盘加载图像之前检查图像是否被缓存。

如果缓存太大或收到内存警告,则需要清空缓存。

高级版本可以为当前滚动位置正下方的单元格预缓存一些图像。

您也许可以为此使用库,也许是带有文件 URL 的 SDWebImage(我还没有尝试过)。

错误的部分是因为您的异步块在加载图像之前没有检查单元格是否没有被重用。如果它有,那么错误的图像将出现在重复使用的单元格上(直到它被另一个图像替换)。要解决此问题,请在加载图像后捕获indexPath块中的 并获取该单元格indexPath- 如果表格视图返回nil,则单元格不再可见,您无需执行任何操作,只需缓存图像以供将来使用。

于 2015-04-12T08:25:30.797 回答