UITableView performance with Realm objects in cellForRowAt indexPath

I have many different category sections in my table view loaded from a named variable allProducts

that contains all my Realm objects (type Results<Product>

).

The correct products are loaded in each section, however, since I entered this piece of code:

switch productViewSegmentedControl!.selectedSegmentIndex {

    case 0:
        allProductsInSection = allProducts.filter("itemgroup = %@", allProductSections[indexPath.section])
    case 1:
        allProductsInSection = allProducts.filter("itembrand = %@", allProductSections[indexPath.section])
    case 2:
        allProductsInSection = allProducts.filter("itemtype = %@", allProductSections[indexPath.section])
    default:
        allProductsInSection = allProducts.filter("itemgroup = %@", allProductSections[indexPath.section])
    }

      

in my method cellForRowAt indexPath

, the UI lags behind when scrolling through the sections of the tableView where there are many items.

Each cell in tableView contains let product = allProductsInSection![indexPath.row]

. The constant product

contains properties for each element from my model class product

.

What can I do to improve the performance of the user interface?

PS each cell is already being reused:

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

      

+3


source to share


2 answers


Having the instruction switch

in your method tableView(_:cellForRowAt:)

means that you are forcing Realm to re-filter the products every time the cell is displayed. From the code you shared, it looks like you have a segmented control that controls which products to display. Rather than checking the selection of the sharded control when preparing each cell, you should instead react to your selection change and filter your products into an instance variable that you can use tableView(_:cellForRowAt:)

. This will allow Realm to filter products only when the criteria have changed, not every time the cell is displayed.

Since you need to filter using a different value in each section of your table view, you need to prepare one Results

for each section of your table view. In the method you call when the selection of the segment control changes:

var productsPerSection = []
for section in 0..numberOfSections {
    let productsInSection: Results<Product>
    switch productViewSegmentedControl!.selectedSegmentIndex {
        case 0:
            productsInSection = allProducts.filter("itemgroup = %@", allProductSections[section])
        case 1:
            productsInSection = allProducts.filter("itembrand = %@", allProductSections[section])
        case 2:
            productsInSection = allProducts.filter("itemtype = %@", allProductSections[section])
        default:
            productsInSection = allProducts.filter("itemgroup = %@", allProductSections[section])
    }
    productsPerSection.append(productsInSection)
}

self.productsPerSection = productsPerSection

      



Then in your method tableView(_:cellForRowAt:)

use self.productsInSection[indexPath.section]

instead of filtering to create allProductsInSection

.

Note: The code is an untested sketch that will hopefully provide a general idea of ​​this approach, but probably won't compile.

+1


source


You have to check if you are decaling your cells correctly. also if you have images in cells it will clean the selected cells well, there is a function called preparation for reuse to clean your cells properly.



0


source







All Articles