I have an array of items and TableView to display them. Item consists of 4 properties. And there is a method which randomly generate items. Initialy, array is empty but in viewDidLoad i have method, which append 100 items to array with delay about 1 second. Array appends until its count about 1_000_000 items. When I start app it freeze.
It’s my tableView methods:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return model.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: DealCell.reuseIidentifier, for: indexPath) as! DealCell
guard model.count != 0 else {
cell.instrumentNameLabel.text = "no data"
cell.priceLabel.text = "no data"
cell.amountLabel.text = "no data"
cell.sideLabel.text = "no data"
return cell
}
cell.instrumentNameLabel.text = "(model[indexPath.row].instrumentName)"
cell.priceLabel.text = "(model[indexPath.row].price)"
cell.amountLabel.text = "(model[indexPath.row].amount)"
cell.sideLabel.text = "(model[indexPath.row].side)"
return cell
}
Function to append array:
server.subscribeToUpdate { updates in
self.model.append(contentsOf: updates)
self.tableView.reloadData()
}
How to solve this problem? May be to make some counter for "numberOfRowsInSection" equal to 100 and then when scroll to 100th item increase it to 200 etc. Or is there a more concise solution?
Tried to use ReusableCell, but nothing happened.
2
Answers
The code below should solve your problem by unblocking the main thread using DispatchQueue
I don’t know what you are really trying to do here… your code seems like it’s just doing a "stress test" or something.
However, to try and help you understand why your app is "freezing" —
Your
for i in 0...dealsCount {
loop will be running very fast. As in maybe 1 or 2 thousandths of a second per 100 iterations. If you are calling.reloadData()
every 100th time through the loop, your code is trying to update the UI pretty much constantly. That means your UI will appear "frozen."Here’s an example that you may find helpful…
First, we’ll add a "status label" and a progress view to display the progress as we generate Deals. We’ll update those every 1000th new Deal created.
Second, as we generate new Deals, we’ll append them directly to the controller’s
var model: [Deal] = []
array (instead of building new arrays and appending them periodically).Third, we’ll only call
.reloadData()
:As I said, I don’t know what you’re really doing … but it is unlikely someone would scroll through the first 1,000 rows before we add the next 100,000 records.
However, you’ll find that you can scroll the table while the records are being generated… and, after they’ve all been generated, selecting any cell will jump to the 900,000th row.
Here’s how it looks:
Deal Struct
Simple multi-line label cell class
Demo view controller
Note: this is Example Code Only!!! It is not intended to be, and should not be considered to be, "production ready."