Search code examples
iphoneobjective-ciosxcodenscache

NSCache does not work


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


Solution

  • 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.