NSCache does not work

3.5k Views Asked by At

I'm writing an app that needs store a few images in cache. I'm trying to do it with NSCache and the code seems to be well but don't save the images in cache. I have this code:

cache is global, declared in .h: NSCache *cache;

-(UIImage *)buscarEnCache:(UsersController *)auxiliarStruct{
    UIImage *image;
    [[cache alloc] init];

    NSLog(@"cache: %i", [cache countLimit]);
    if ([cache countLimit] > 0) { //if [cache countLimit]>0, it means that cache isn't empty and this is executed
        if ([cache objectForKey:auxiliarStruct.thumb]){    
            image = [cache objectForKey:auxiliarStruct.thumb];
        }else{ //IF isnt't cached, is saved
            NSString *imageURLString = [NSString stringWithFormat:@"http://mydomain.com/%@",auxiliarStruct.thumb];
            NSURL *imageURL = [NSURL URLWithString:imageURLString];
            NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
            image = [UIImage imageWithData:imageData];
            [cache setObject:image forKey:auxiliarStruct.thumb];
        }        
    }else{ //This if is executed when cache is empty. IS ALWAYS EXECUTED BECAUSE FIRST IF DOESN'T WORKS CORRECTLY
        NSString *imageURLString = [NSString stringWithFormat:@"http://mydomain.com/%@",auxiliarStruct.thumb];
        NSURL *imageURL = [NSURL URLWithString:imageURLString];
        NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
        image = [UIImage imageWithData:imageData];
        [cache setObject:image forKey:auxiliarStruct.thumb];
    }
    return image;
}

This function is called in other function with this:

      UIImage *image = [self buscarEnCache:auxiliarStruct];

This works because the image is displayed on screen but isn't saved in cache, the line that I think fails is:

[cache setObject:image forKey:auxiliarStruct.thumb]; //auxiliarStruct.thumb is the name of the image

Someone knows why cache doesn't work?? Thanks!!

ps: sorry for my english, I know is bad

2

There are 2 best solutions below

2
On BEST ANSWER

Every time the method buscarEnCache: is called an new cache object is created with the line:

[[cache alloc] init];

Thus the old cache just leaked and is not available any more.

place the cache = [[NSCache alloc] init]; in the init method of the class.


There is no need to check for the countLimit.

-(UIImage *)buscarEnCache:(UsersController *)auxiliarStruct{
    UIImage *image = [cache objectForKey:auxiliarStruct.thumb];

    if (!image) {    
        NSString *imageURLString = [NSString stringWithFormat:@"http://mydomain.com/%@",auxiliarStruct.thumb];
        NSURL *imageURL = [NSURL URLWithString:imageURLString];
        NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
        image = [UIImage imageWithData:imageData];
        [cache setObject:image forKey:auxiliarStruct.thumb];
    }

    return image;
}

You might want to place the fetch of the image in a method that runs in an other thread and return some kind of placeholder image.

1
On

As well as the answer provided by @rckoenes, you aren't allocating the cache instance correctly anyway; it should be:

cache = [[NSCache alloc] init];

Which should be moved into your init method.