在顯示UITableView 或 UICollectionView 要一起帶入有圖檔的時候,可以先把畫面顯示出來之後,在去下載圖片並顯示出來,方法如下:
要先新增一個class ImageRequest
繼承NSMutableURLRequest
ImageRequest.h
#import
#define kIMAGE_REQUEST_CACHE_LIMIT 100
typedef void (^CompletionBlock) (UIImage *, NSError *);
@interface ImageRequest : NSMutableURLRequest
- (UIImage *)cachedResult;
- (void)startWithCompletion:(CompletionBlock)completion;
@end
ImageRequest.m
#import "ImageRequest.h"
NSMutableDictionary *_inflight;
NSCache *_imageCache;
@implementation ImageRequest
- (NSMutableDictionary *)inflight {
if (!_inflight) {
_inflight = [NSMutableDictionary dictionary];
}
return _inflight;
}
- (NSCache *)imageCache {
if (!_imageCache) {
_imageCache = [[NSCache alloc] init];
_imageCache.countLimit = kIMAGE_REQUEST_CACHE_LIMIT;
}
return _imageCache;
}
- (UIImage *)cachedResult {
return [self.imageCache objectForKey:self];
}
- (void)startWithCompletion:(CompletionBlock)completion {
UIImage *image = [self cachedResult];
if (image) return completion(image, nil);
NSMutableArray *inflightCompletionBlocks = [self.inflight objectForKey:self];
if (inflightCompletionBlocks) {
// a matching request is in flight, keep the completion block to run when we're finished
[inflightCompletionBlocks addObject:completion];
} else {
[self.inflight setObject:[NSMutableArray arrayWithObject:completion] forKey:self];
[NSURLConnection sendAsynchronousRequest:self queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
// build an image, cache the result and run completion blocks for this request
UIImage *image = [UIImage imageWithData:data];
[self.imageCache setObject:image forKey:self];
id value = [self.inflight objectForKey:self];
[self.inflight removeObjectForKey:self];
for (CompletionBlock block in (NSMutableArray *)value) {
block(image, nil);
}
} else {
[self.inflight removeObjectForKey:self];
completion(nil, error);
}
}];
}
}
@end
在UICollectionView上使用的時候
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
NSURL *url = [NSURL URLWithString:@"http:// some url from your model"];
// note that this can be a web url or file url
ImageRequest *request = [[ImageRequest alloc] initWithURL:url];
UIImage *image = [request cachedResult];
if (image) {
UIImageView *imageView = (UIImageView *)[cell viewWithTag:127];
imageView.image = image;
} else {
[request startWithCompletion:^(UIImage *image, NSError *error) {
if (image && [[collectionView indexPathsForVisibleItems] containsObject:indexPath]) {
[collectionView reloadItemsAtIndexPaths:@[indexPath]];
}
}];
}
cell.photoView.image = image;
return cell;
}
出處:
http://stackoverflow.com/questions/15799432/poor-uicollectionview-scrolling-performance-with-uiimage/15799771#15799771