2017-07-18 125 views
0

我正在构建一个国家选择器UITableViewController,其中每个UITableViewCell包含该国的国旗UIImage。我试图在主线程加载每个单元的从.xcassetsUIImage对象在我tableView(_:cellForRowAt:),像这样:快速从磁盘加载UITableViewCell图像

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

     let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 
     let imageName = UIImage(named: "US.png") 
     imageView?.image = UIImage(named: imageName) 
     return cell 
} 

这将产生大约〜46的FPS。然后我尝试异步操作:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

      let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 

      DispatchQueue.main.async { 
       let imageName = UIImage(named: "US.png") 
       imageView?.image = UIImage(named: imageName) 
      } 

      return cell 
    } 

它将我的滚动FPS提高到55,这并不可怕。但我认为它可以进一步优化。

从高性能可滚动的UITableView中快速加载磁盘映像的最佳方式是什么?第三方库?

回答

1

你还在加载在主线程,大概就像

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 

    DispatchQueue("Somequeue").async { 
     let imageName = UIImage(named: "US.png") 
     DispatchQueue.main.async { 
      imageView?.image = UIImage(named: imageName) 
     } 
    } 

    return cell 
} 

将是一个有点快。图像被加载远离主线程,一旦它被加载,你回到主线程来设置图像。但是,如果快速滚动,这种方法可能会导致一些奇怪的行为。单元格将被重用,如果旧图像在最新映像之后加载,您最终可能会在单元格上设置错误的图像。

最好实现某种使用自己的DispatchQueue的队列机制,并知道如何取消或忽略旧的请求。

重点是把图像加载远离主线:)