显示图像时,UITableView滞后

Mah*_*aha 4 image uitableview nsdata ios swift

我有一个tableView在单元格中显示图像,我正在viewDidLoad函数中获取数据

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
                let cell = tableview.dequeueReusableCellWithIdentifier("cardSelectionCell", forIndexPath: indexPath) as! MyCell
                let card = fetchedResultsController.objectAtIndexPath(indexPath) as! Card
                cell.Name?.text = card.name
                var image: NSData = card.photo as NSData
                cell.logo.image = UIImage(data: image)
                let date = NSDate()
                let formatter = NSDateFormatter()
                formatter.timeStyle = .MediumStyle
                cell.policyExpiryDate.text = formatter.stringFromDate(date)
                return cell 
        }
Run Code Online (Sandbox Code Playgroud)

但问题是,当我开始滚动时,tableView非常滞后所以我试图创建一个字典来转换viewDidLoad()中的图像

var imageDictionary = [Card:UIImage]()


AllCards = context.executeFetchRequest(request, error: nil) as! [Card]
        for card in AllCards {
            imageDictionary[card] = UIImage(data: card.photo as NSData)
        }
Run Code Online (Sandbox Code Playgroud)

并在tableView功能:

cell.logo.image = imageDictionary[card]
Run Code Online (Sandbox Code Playgroud)

但它仍然落后

还有一个问题:如果一张卡被添加到核心数据中,我必须再次获取图像数组,所以我尝试创建数组,viewDidAppear()但图像不会出现在第一次加载中,而tableView仍然滞后.

kat*_*000 6

首先,它取决于你的图像大小:

var image: NSData = card.photo as NSData
cell.logo.image = UIImage(data: image)
Run Code Online (Sandbox Code Playgroud)

这条线可能很重.您可以像这样轻松地测量它,例如:

let time1 = CACurrentMediaTime()
var image: NSData = card.photo as NSData
cell.logo.image = UIImage(data: image)
print(CACurrentMediaTime() - time1)
Run Code Online (Sandbox Code Playgroud)

如果需要花费很多时间(例如超过8毫秒),那么应该优化它.您可以通过多种方式执行此操作,例如,您可以将UIImage引用存储在某些字典或数组中,然后传递显示cellForIndexPath:.另一种方法是使用AsyncKit方式 - 使您的UI同步,在一个线程中加载数据并将其传递给仅在主线程上绘制.现在你所有的进程都在主线程中.

UPD:我认为在这种情况下最好的方法是将pathes存储到图像中,然后在后台运行UIImage调整大小并返回预览.你也可以为调整大小和未调整大小的UIImage制作缓存,路径或URL可以是一个键 - 所以下次只需要从缓存中取出UIImage而不是再次启动所有调整大小的过程.

还要注意这个操作:

cell.logo.image = UIImage(data: image)
Run Code Online (Sandbox Code Playgroud)

创建一个系统缓存,并可以在内存中进行大量分配,因为垃圾收集器不会立即杀死它,就像在情况下一样UIWebView.所以你可以在你的函数周围添加你自己的自动释放池:

autoreleasepool { () -> () in
    cell.logo.image = UIImage(data: image)
}
Run Code Online (Sandbox Code Playgroud)