Table View with Images, slow load and scroll

前端 未结 4 976
死守一世寂寞
死守一世寂寞 2020-12-12 06:55

I tried impletmenting about 30 tutorials today and just cant get anything to work.

My problem is that i load my information via a JSON file, add the data to a NSMuta

相关标签:
4条回答
  • 2020-12-12 07:10

    You should use asynchronous image retrieval provided by UIImageView categories found in AFNetworking or SDWebImage. These categories:

    • are incredibly easy to use (rather than using the UIImageView method setImage, instead use one of the categories' setImageWithURL methods);

    • provide asynchronous image retrieval;

    • cache the downloaded images with NSCache, to make sure you don't have to retrieve images that you just downloaded;

    • ensure that your UI cannot get backlogged downloading images for cells that have scrolled off screen; and

    • leverage operation queues to constrain the degree of concurrency (rather than using GCD global queues that can result in timeout failures).

    0 讨论(0)
  • 2020-12-12 07:12

    I have a class that I call RemoteImageHandler. Here is the .h file:

    #import <UIKit/UIKit.h>
    
    @interface RemoteImageHandler : NSObject
    
    - (void)imageForUrl:(NSURL*)url callback:(void(^)(UIImage *image))callback;
    
    + (RemoteImageHandler *)shared;
    
    @end
    

    And the .m file:

    #import "RemoteImageHandler.h"
    
    @interface RemoteImageHandler ()
    
    @property (nonatomic, strong) NSMutableDictionary *imageDictionary;
    
    @end
    
    @implementation RemoteImageHandler
    
    - (void)imageForUrl:(NSURL*)url callback:(void(^)(UIImage *image))callback {
        if (!!self.imageDictionary[url]) {
            callback(self.imageDictionary[url]);
        } else {
            dispatch_async(dispatch_get_global_queue(0,0), ^{
                NSData * data = [[NSData alloc] initWithContentsOfURL:url];
                if (data == nil)
                    callback(nil);
                dispatch_async(dispatch_get_main_queue(), ^{
                    UIImage *image = [UIImage imageWithData:data];
                    self.imageDictionary[url] = image;
                    callback(image);
                });
            });
        }
    }
    
    + (TQRemoteImageHandler *)shared {
        static TQRemoteImageHandler *shared = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            shared = [[self alloc] init];
        });
        return shared;
    }
    
    @end
    

    In my table view, whenever I want an image from a remote location (let's say this is in cellForRowAtIndexPath, I use this:

    - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier forIndexPath:indexPath];
    
        [[RemoteImageHandler shared] imageForUrl:someURLCorrespondingToTheImageYouWant callback:^(UIImage *image) {
            cell.imageView.image = image;
        }];
    
        return cell;
    }
    
    0 讨论(0)
  • 2020-12-12 07:33

    Take a look at Apple's LazyTableImages example. Basically it comes down to

    a) reusing your table cells

    b) only loading images that are currently visible

    0 讨论(0)
  • 2020-12-12 07:34

    You kinda left your problem wide open b/c you weren't specific enough. Performance issues can be related to a bunch of things. Here are a few performance things with tableview cells & images

    • Load images on a background thread.

    • Reuse cells - don't allocate any more than you need on screen

    static NSString *CellIdentifier = @"Cell";
    
        CellClass *cell = (CellClass*)[tv dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) cell = [[[CellClass alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    

    • Only draw images that are the same size of the cell (ie. if a cell is 44 px high, keep UIimages at 44px). If images are bigger, you might have to process the images after downloading them from the internet.

    • Don't use uiimageview in your cell. instead create a custom cell (ie. subclass) and draw the image in your drawRect: function.

    0 讨论(0)
提交回复
热议问题