Search code examples
iosswiftuitableviewrealmgrand-central-dispatch

GCD Returning Incorrect Results in UITableView


I have a list of about 8,500 items that load in a UITableView and there should be only about 200 items in which product.isnewitem is true. For every 'new' item, an image (newicon.png) is supposed to load indicating that it is a new item; however, when I start scrolling down on the table view, newicon shows up on over 50% of the items. All the items are loaded via Realm.

The check for new items is done in:

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

Here is the entire cellForRowAtIndexPath method:

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
}

Solution

  • I can’t understand why you use this code

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

    two times in your cellForRowAtIndexPath and one in a queue, I think you must move this code to your viewController viewDidLoad, or viewWillAppear and then use the products from a local array declared on your 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")
    }
    

    and in your cellForRowAtIndexPath you should have something like this

    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
    }
    

    I hope this helps you