2017-03-31 34 views
0

我有一个在UITableView中加载的大约8,500个项目的列表,并且应该只有大约200个项目,其中product.isnewitem为真。对于每个'新'项目,图像(newicon.png)应该加载,表明它是一个新项目;然而,当我开始在桌面视图上滚动时,newicon显示了超过50%的项目。所有物品都通过Realm加载。GCD在UITableView中返回不正确的结果

的新项目的检查是在:

if product.isnewitem { 
     cell.newIconImageView.image = #imageLiteral(resourceName: "newicon.png") 
    } 

这里是整个的cellForRowAtIndexPath方法:

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

    let paths = NSSearchPathForDirectoriesInDomains(documentsDirectory, userDomainMask, true) 

    let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell") as? OrderFormViewCell 
     ?? UITableViewCell(style: .subtitle, reuseIdentifier: "ProductCell") as! OrderFormViewCell 

    let realm = try! Realm() 
    let allProducts = realm.objects(Product.self).sorted(byKeyPath: "basedescription") 
    let product = allProducts[indexPath.row] 

    cell.productDescriptionLabel.text = product.basedescription 

    queue.async { 
     let realm = try! Realm() 

     let allProducts = realm.objects(Product.self).sorted(byKeyPath: "basedescription") 
     let product = allProducts[indexPath.row] 

     if product.isnewitem { 
      cell.newIconImageView.image = #imageLiteral(resourceName: "newicon.png") 
     } 

     if let dirPath = paths.first { 
      let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent("T\(product.itemno.replacingOccurrences(of: "-", with: "")).png") 

      if let image = UIImage(contentsOfFile: imageURL.path) { 
       cell.productImageView.image = image 
      } 
      else { 
       cell.productImageView.image = #imageLiteral(resourceName: "image-coming-soon.png") 
      } 
     } 


    } 



    return cell 
} 
+1

你不应该在'cellForRow(at:)'中发出异步获取请求。单元格被重用,所以在读取完成时,单元格可能已被重新用于另一行。如果该项目不是新的,还要确保明确地清除“新”图像。 – Paulw11

+0

@ Paulw11我应该在哪里放异步调用?我需要使用某种后台线程,以便UI不会滞后,因此我需要访问IndexPath,因为每个产品图像对于每个单元格都是唯一的。它应该是一个同步调用吗?最后,“清理”“新”图像意味着什么? – Sicypher

回答

1

我不明白为什么您使用此代码

let realm = try! Realm() 
let allProducts = realm.objects(Product.self).sorted(byKeyPath: "basedescription") 
let product = allProducts[indexPath.row] 

两次在您的cellForRowAtIndexPath和一个队列中,我认为您必须将此代码移动到您的viewControllerviewDidLoad,或viewWillAppear,然后使用这些产品从本地阵列宣布对你的viewController

var allProducts : Results<Product>? 

override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 
    let realm = try! Realm() 
    self.allProducts = realm.objects(Product.self).sorted(byKeyPath: "basedescription") 
} 

,并在你的cellForRowAtIndexPath你应该有这样的事情

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

let paths = NSSearchPathForDirectoriesInDomains(documentsDirectory, userDomainMask, true) 

let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell") as? OrderFormViewCell 
    ?? UITableViewCell(style: .subtitle, reuseIdentifier: "ProductCell") as! OrderFormViewCell 

let product = self.allProducts[indexPath.row] 
cell.productDescriptionLabel.text = product.basedescription 
if product.isnewitem { 
     cell.newIconImageView.image = #imageLiteral(resourceName: "newicon.png") 
    } 
else { 
     cell.newIconImageView.image = nil 
    } 

    if let dirPath = paths.first { 
     let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent("T\(product.itemno.replacingOccurrences(of: "-", with: "")).png") 

     if let image = UIImage(contentsOfFile: imageURL.path) { 
      cell.productImageView.image = image 
     } 
     else { 
      cell.productImageView.image = #imageLiteral(resourceName: "image-coming-soon.png") 
     } 
    } 

return cell 
} 

我希望这可以帮助你

+0

我在这个方法中有两个Realm实例,因为Realm要求你在每个线程中都有一个新的实例。一个Realm实例不能在多个线程中使用。 – Sicypher

+0

但为什么你需要2个线程? –

+0

图像需要在表格视图中的后台线程上加载,因为如果加载到主线程上,它将显着影响UI。 – Sicypher