2017-03-31 8 views
0

私はUITableViewにロードする約8,500項目のリストを持っており、product.isnewitemが真である約200個の項目しかないはずです。すべての「新しい」アイテムに対して、新しいアイテムであることを示すイメージ(newicon.png)がロードされるはずです。しかし、私がテーブルビューをスクロールダウンすると、newiconがアイテムの50%以上に表示されます。すべてのアイテムはレルム経由でロードされます。GITはUITableViewで正しくない結果を返す

新しい項目のチェックがで行われます。

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

役に立てば幸いこの

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 } 

のようなものを持っている必要があります'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] 
を使用する理由私は理解することはできません。ここで

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

全体cellForRowAtIndexPathメソッドがあります

あなたのcellForRowAtIndexPathで2回、待ち行列に入っている場合は、このコードをに移動する必要がありますviewDidLoad、または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であなたは、私はこれがあなた

+0

Realmは各スレッドに新しいインスタンスを必要とするため、このメソッドでは2つのRealmインスタンスがあります。 1つのRealmインスタンスを複数のスレッドにわたって使用することはできません。 – Sicypher

+0

しかし、なぜ2つのスレッドが必要ですか? –

+0

イメージは、メインスレッドにロードされるとUIに大きな影響を与えるため、テーブルビューのバックグラウンドスレッドにロードする必要があります。 – Sicypher

関連する問題