Note that there are some explanatory texts on larger screens.

plurals
  1. POUITableView gets Slower with every new NSMutableArray
    primarykey
    data
    text
    <p>I have a UITableView that populates the results of a search that the user looks up. In order to do this I am using a NSMutableArray of Dictionaries where objects are added for the first 10, and then when the user scrolls to the bottom it populates the next 10 until there are no results left to show.</p> <p>This all works well and good but I started to notice that the more searches that are done, the slower the table gets. Here is some of the code:</p> <pre><code>- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { [self.objectsArray removeAllObjects]; [self.objectsArray setArray:nil]; [itemsTable reloadData]; [itemsTable scrollRectToVisible:CGRectMake(0, 0, 0, 0) animated:false]; [self loadItemsFromURL:searchURL withItemDescription:encodedString atStartRow:start andEndRow:end]; } </code></pre> <p>The above is when a new search is performed. It then does a NSURLConnection and responds with this:</p> <pre><code>- (void)connectionDidFinishLoading:(NSURLConnection *)connection { if (self.objectsArray == nil) self.objectsArray = [NSMutableArray array]; // self.objectsArray = [[NSMutableArray alloc] init]; NSError *error; NSDictionary *returnArray = [[NSJSONSerialization JSONObjectWithData:itemsData options:kNilOptions error:&amp;error] valueForKey:@"items"]; for (id key in returnArray) { [self.objectsArray addObject:[returnArray objectForKey:key]]; } counter += 10; [itemsTable reloadData]; } </code></pre> <p>As you can see, if a user conducts a new search all objects are removed with <code>[self.objectsArray removeAllObjects]</code>and I even try to set the array to <code>nil</code>. If I perform multiple searches the <code>UITableView</code> gets slower and slower with scrolling each time. It is almost like the controller sees the array as getting larger and larger with each search even though I am removing all of the objects from it before the search. Any ideas or am I going about this the wrong way?</p> <p><strong>EDIT:</strong> Here is the <code>cellForRowAtIndexPath:</code> method. <code>cell</code> is a subclassed <code>UITableViewCell</code>.</p> <pre><code>- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Product Cell"; static NSString *LoadCellIdentifier = @"Loading Cell"; cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if ([self.objectsArray count] &lt;= 0 ) { cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; cell.itemName.text = @"No items found."; cell.itemPrice.text = @""; cell.itemLocation.text = @""; cell.addButton.hidden = YES; } else { if ([indexPath row] == [self.objectsArray count]) { if ( [self.objectsArray count] &gt;= 10 ) { if ( [self.objectsArray count] &lt; counter) { cell = [tableView dequeueReusableCellWithIdentifier:LoadCellIdentifier]; [cell.loadingSpinner stopAnimating]; cell.itemName.text = @"No more items found."; } else { if (!running) { [self loadItemsFromURL:searchURL withItemDescription:encodedString atStartRow:[self.objectsArray count] + 1 andEndRow:[self.objectsArray count] + 10]; cell = [tableView dequeueReusableCellWithIdentifier:LoadCellIdentifier]; cell.itemName.text = @"Loading more items..."; [cell.loadingSpinner startAnimating]; running = true; } else { cell = [tableView dequeueReusableCellWithIdentifier:LoadCellIdentifier]; [cell.loadingSpinner startAnimating]; } } } } else { cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; NSArray *match = [self.objectsArray objectAtIndex:[indexPath row]]; cell.addButton.hidden = NO; if ([match valueForKey:@"DESCRIPTION"] == [NSNull null] ) { cell.itemName.text = @"Description not available."; } else { cell.itemName.text = [match valueForKey:@"DESCRIPTION"]; } if ([match valueForKey:@"AD"] != [NSNull null]) { NSMutableString *adString = [NSMutableString stringWithString:[match valueForKey:@"AD"]]; NSRange textRange; textRange = [adString rangeOfString:@"1/"]; if (textRange.location != NSNotFound) { [adString replaceCharactersInRange:[adString rangeOfString:@"1/"] withString:@"$"]; } else { [adString replaceCharactersInRange:[adString rangeOfString:@"/"] withString:@"/$"]; } cell.itemPrice.text = adString; } else if ([match valueForKey:@"REGULAR"] == [NSNull null]) { cell.itemPrice.text = @"$ N/A"; } else { NSNumberFormatter *currencyStyle = [[NSNumberFormatter alloc] init]; [currencyStyle setFormatterBehavior:NSNumberFormatterBehavior10_4]; [currencyStyle setNumberStyle:NSNumberFormatterCurrencyStyle]; NSNumber *price = [NSNumber numberWithDouble:[[match valueForKey:@"REGULAR"] doubleValue]]; NSString *stringPrice = [currencyStyle stringFromNumber:price]; cell.itemPrice.text = [NSString stringWithFormat:@"%@", stringPrice]; } if ([match valueForKey:@"AISLE"] == [NSNull null]) { cell.itemLocation.text = @"Item location: N/A"; } else { cell.itemLocation.text = [NSString stringWithFormat:@"Item Location: %@", [match valueForKey:@"AISLE"]]; } match = nil; } } return cell; } </code></pre> <p><strong>EDIT 2:</strong> Here is a snippet of what the JSON looks like:</p> <pre><code>{ items = { 263149 = { AD = "###"; AISLE = 6A; DESCRIPTION = "Cinnamon Toasters"; R = 9; REGULAR = "#.##"; }; 26599 = { AD = "####"; AISLE = 6A; DESCRIPTION = "Quaker Life Cereal"; R = 2; REGULAR = "#.##"; }; 40517 = { AD = "###"; AISLE = 6A; DESCRIPTION = "Toasted Oats"; R = 1; REGULAR = "#.##"; }; }; }; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload