Custom table table scrolling

I have a table view that displays custom cells, the cells contain an image that I load from the docs folder. I notice that when I look at the table, there is some lag, which, I believe, comes from loading the image from disk. However, the image is already uploaded to the point, so I'm a bit confused.

Suggestions for optimizing this code will be appreciated. I read about lazy loading, but I'm not sure if this applies to me or not.

I checked that the table reuses cells.

Edit:

- (void)configureCell:(BeerCell *)cell atIndexPath:(NSIndexPath *)indexPath { Beer *beer = (Beer *) [self.fetchedResultsController objectAtIndexPath:indexPath]; cell.displayBeerName.text = beer.name; // check to see if there is a cached image already. Use a dictionary. // make sure this is one of your ivars __block UIImage *theImage = [self.imagesCache objectForKey: beer.imagePath]; // If the image is not in your cache, you need to retrieve it. if (!theImage){ // The image doesn't exist, we need to load it from disk, web or render it // First put a placeholder image in place. Shouldn't be any penalties after the // first load because it is cached. cell.beerImage.image = [UIImage imageNamed:@"beer-pic.png"]; // check to see if your image cache dictionary has been created, if not do so now if (_imagesCache == nil) { _imagesCache= [[NSMutableDictionary alloc] initWithCapacity:1]; } // get a weak reference to UITableViewController subclass for use in the block // we do this to avoid retain cycles __weak BeerListViewController *weakSelf = self; // do the heavy lifting on a background queue so the UI looks fast dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); dispatch_async(queue, ^ { theImage = [UIImage imageWithContentsOfFile:beer.imagePath]; // I added this in because I create the new core data object in this class, and pass // it to the class where I fill out the information about the beer if (theImage) { // Add the image to the cache [weakSelf.imagesCache setObject:theImage forKey:beer.imagePath]; //[weakSelf.imagesCache addObject:theImage forKey:beer.imagePath]; // Check to see if the cell for the specified index path is still being used BeerCell *theCell = (BeerCell *)[weakSelf.tableView cellForRowAtIndexPath:indexPath]; // Per the docs. An object representing a cell of the table // or nil if the cell is not visible or indexPath is out of range. if (theCell){ // dispatch onto the main queue because we are doing work on the UI dispatch_async(dispatch_get_main_queue(), ^ { theCell.beerImage.image = theImage; [theCell setNeedsLayout]; }); } } }); } else { // Image already exists, use it. cell.beerImage.image = theImage; } } 
0
source share
3 answers

Whenever you load from a disk, server, or render images to view a table, you will want to place it in the background. It's trivial to do and get great performance even on 3GS.

I use a similar approach to create thumbnails for table views and view scrolling from very large images, and the performance is very good.

Try the following:

 - (void)configureCell:(CustomCell *)cell atIndexPath:(NSIndexPath *)indexPath { CoreDateObject *object = (CoreDateObject *)[self.fetchedResultsController objectAtIndexPath:indexPath]; cell.displayName.text = object.name; // check to see if there is a cached image already. Use a dictionary. // make sure this is one of your ivars UIImage *theImage=[self.imagesCache objectForKey: object.imagePath]; // If the image is not in your cache, you need to retrieve it. if (!theImage){ // The image doesn't exist, we need to load it from disk, web or render it // First put a placeholder image in place. Shouldn't be any penalties after the // first load because it is cached. cell.selectedImage.image=[UIImage imageNamed:@"yourPlaceHolderImage"]; // check to see if your image cache dictionary has been created, if not do so now if (_imagesCache==nil){ _imagesCache=[NSMutableDictionary alloc] initWithCapacity:1]; } // get a weak reference to UITableViewController subclass for use in the block // we do this to avoid retain cycles __weak YourTableViewControllerSubclass *weakSelf=self; // do the heavy lifting on a background queue so the UI looks fast dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); dispatch_async(queue, ^{ theImage=[UIImage imageWithContentOfFile:object.imagePath]; // Add the image to the cache [weakSelf.imagesCache addObject:theImage forKey:object.imagePath]; // Check to see if the cell for the specified index path is still being used CustomCell *theCell=(CustomCell *)[weakSelf.tableView cellForRowAtIndexPath:indexPath]; // Per the docs. An object representing a cell of the table // or nil if the cell is not visible or indexPath is out of range. if (theCell){ // dispatch onto the main queue because we are doing work on the UI dispatch_async(dispatch_get_main_queue(), ^{ theCell.selectedImage.image=theImage [theCell setNeedsLayout]; }); } }else{ // Image already exists, use it. cell.selectedImage.image=theImage; } cell.rating.rate = object.rating.doubleValue; } 
+1
source

one of these two links will better explain how to do this correctly.

https://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html (official apple)

https://github.com/rs/SDWebImage (good library to use) ..

0
source

cellForRowAtIndexPath: called every time you look at the table view ... So it could be your scroll freeze if you write large processing code in this method. Therefore, for this, make an array of your images, if possible, then use thumbnail images .... then add these images to the cell from the array. I'm sure your scroll will be smooth.

0
source

Source: https://habr.com/ru/post/920499/


All Articles