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.

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top