自定义表格单元格滚动

我有一个表格视图,显示自定义单元格,单元格包含我从文档文件夹加载的图像。 我注意到,当我滚动表时,有一些滞后,我假设来自加载磁盘上的图像。 然而,图像已经加载在这一点,所以我有点困惑。

对于优化这个代码的build议,将不胜感激。 我读过关于延迟加载,但我不知道这是否适用于我。

我确实检查了一下桌子是否在重复使用这些单元格。

编辑:

- (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; } } 

无论何时从磁盘,服务器或渲染图像为桌面视图加载,你都希望把它放在后台队列中。 这样做是微不足道的,即使在3GS上也会获得很好的性能。

我使用类似的方法来从非常大的图像生成tableviews和滚动视图的缩略图,性能非常好。

尝试这个:

 - (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; } 

这两个链接之一将更好地解释如何做到这一点。

https://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html (官方苹果)

https://github.com/rs/SDWebImage (很好的库使用)..

cellForRowAtIndexPath:每当你滚动表视图时被调用…因此,如果你在这个方法中编写大的处理代码,它可以挂起你的滚动。 因此,如果可能,请使用缩略图….然后将这些图像添加到数组中的单元格中。 我相信你的滚动会很顺利。