immagini URL Cache iphone UITableView
-
20-09-2019 - |
Domanda
Sono alla ricerca di un tutorial su come memorizzare nella cache le immagini caricate da un URL in cellule di un UITableView.
ho trovato qui un esempio
http: //www.ericd. net / 2009/05 / iphone-cache-immagini-in-memory.html # top
Ma il codice è incompleto. Sono un novizio c obiettivo così ho trovato molto difficile riempire i pezzi mancanti.
Soluzione 2
Un esempio di lavoro piacevole è stato trovato qui
http://ezekiel.vancouver.wsu.edu/~wayne/ Calabrone / YellowJacket.zip
Altri suggerimenti
Ecco una semplice implementazione imagecache utilizzando NSCache. Imagecache è un singelton.
ImageCache.h
#import <Foundation/Foundation.h>
@interface ImageCache : NSObject
@property (nonatomic, retain) NSCache *imgCache;
#pragma mark - Methods
+ (ImageCache*)sharedImageCache;
//- (void) AddImage:(NSString *)imageURL: (UIImage *)image;
- (void) AddImage:(NSString *)imageURL withImage:(UIImage *)image;
- (UIImage*) GetImage:(NSString *)imageURL;
- (BOOL) DoesExist:(NSString *)imageURL;
@end
ImageCache.m
#import "ImageCache.h"
@implementation ImageCache
@synthesize imgCache;
#pragma mark - Methods
static ImageCache* sharedImageCache = nil;
+(ImageCache*)sharedImageCache
{
@synchronized([ImageCache class])
{
if (!sharedImageCache)
sharedImageCache= [[self alloc] init];
return sharedImageCache;
}
return nil;
}
+(id)alloc
{
@synchronized([ImageCache class])
{
NSAssert(sharedImageCache == nil, @"Attempted to allocate a second instance of a singleton.");
sharedImageCache = [super alloc];
return sharedImageCache;
}
return nil;
}
-(id)init
{
self = [super init];
if (self != nil)
{
imgCache = [[NSCache alloc] init];
}
return self;
}
// - (void) AddImage:(NSString *)imageURL: (UIImage *)image
- (void) AddImage:(NSString *)imageURL withImage:(UIImage *)image
{
[imgCache setObject:image forKey:imageURL];
}
- (NSString*) GetImage:(NSString *)imageURL
{
return [imgCache objectForKey:imageURL];
}
- (BOOL) DoesExist:(NSString *)imageURL
{
if ([imgCache objectForKey:imageURL] == nil)
{
return false;
}
return true;
}
@end
Esempio
UIImage *image;
// 1. Check the image cache to see if the image already exists. If so, then use it. If not, then download it.
if ([[ImageCache sharedImageCache] DoesExist:imgUrl] == true)
{
image = [[ImageCache sharedImageCache] GetImage:imgUrl];
}
else
{
NSData *imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: imgUrl]];
image = [[UIImage alloc] initWithData:imageData];
// Add the image to the cache
//[[ImageCache sharedImageCache] AddImage:imgUrl :image];
[[ImageCache sharedImageCache] AddImage:imgUrl withImage:image];
}
Si potrebbe anche provare a utilizzare la libreria EgoImage impressionante scritta dai compagni taglienti a enormego per raggiungere questo obiettivo. E 'molto semplice da usare, fa un uso efficiente delle cache di dietro le quinte ed è ideale per soddisfare le vostre esigenze.
Ecco il github percorso per la libreria che include un'applicazione demo.
ho scritto questo (con concetti e qualche codice preso da eccellente UIImageView + categoria cache di Lane Roathe) per un app sto lavorando su. Esso utilizza il ASIHTTPRequest classi pure, che sono grandi. Questo potrebbe sicuramente essere migliorato .. per esempio, consentendo richieste di essere cancellati se non sono più necessari, oppure utilizzando l'userInfo di notifica per consentire una più precisa l'aggiornamento dell'interfaccia utente .. ma che sta funzionando bene per i miei scopi.
@implementation ImageFetcher
#define MAX_CACHED_IMAGES 20
static NSMutableDictionary* cache = nil;
+ (void)asyncImageFetch:(UIImage**)anImagePtr withURL:(NSURL*)aUrl {
if(!cache) {
cache = [[NSMutableDictionary dictionaryWithCapacity:MAX_CACHED_IMAGES] retain];
}
UIImage* newImage = [cache objectForKey:aUrl.description];
if(!newImage) { // cache miss - doh!
ASIHTTPRequest *imageRequest = [ASIHTTPRequest requestWithURL:aUrl];
imageRequest.userInfo = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:anImagePtr] forKey:@"imagePtr"];
imageRequest.delegate = self;
[imageRequest setDidFinishSelector:@selector(didReceiveImage:)];
[imageRequest setDidFailSelector:@selector(didNotReceiveImage:)];
[imageRequest startAsynchronous];
}
else { // cache hit - good!
*anImagePtr = [newImage retain];
}
}
+ (void)didReceiveImage:(ASIHTTPRequest *)request {
NSLog(@"Image data received.");
UIImage **anImagePtr = [(NSValue*)[request.userInfo objectForKey:@"imagePtr"] pointerValue];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *newImage = [[UIImage imageWithData:[request responseData]] retain];
if(!newImage) {
NSLog(@"UIImageView: LoadImage Failed");
}
else {
*anImagePtr = newImage;
// check to see if we should flush existing cached items before adding this new item
if( [cache count] >= MAX_CACHED_IMAGES)
[cache removeAllObjects];
[cache setValue:newImage forKey:[request url].description];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName: @"ImageDidLoad" object: self userInfo:request.userInfo];
}
[pool drain];
}
Si chiama questo codice come segue:
[ImageFetcher asyncImageFetch:&icon withURL:url];
Sono anche utilizzando le notifiche, bene o male, di lasciare che tutti i proprietari del corrispondente UIImage sapere quando dovrebbero redisplay- in questo caso, è in un contesto tableView:
- (void)viewDidLoad {
[super viewDidLoad];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(imageDidLoad:) name:@"ImageDidLoad" object:nil];
}
- (void)imageDidLoad:(NSNotification*)notif {
NSLog(@"Received icon load notification.");
// reload table view so that new image appears.. would be better if I could
// only reload the particular UIImageView that holds this image, oh well...
[self.tableView reloadData];
}
- (void)dealloc {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self];
// ...
}
Si potrebbe anche desiderare di controllare HJCache . Viene fornito con un UIImageView compatibile con classe di visualizzazione che fa tutto il caching in modo trasparente ed è adatto per essere utilizzato in UITableViewCells dove le prestazioni di scorrimento è importante.