1

I have a wierd problem. The requirement is to download image from a url on swipe and display it in image view .It is working all fine but I am getting memory warnings after 30 images and after few more swipe app crashes.

Implementation is pretty straight forward,but already spent almost 2 days to figure out the issue. On each swipe i am calling A method :-

-(void)callDownloadImageAPI{

    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
    [self loadIndicator:@"Please Wait.!!" :@"Please be patient while we are downloading image for you"];
    @try{
        DownloadImage *downLoadImge =[[DownloadImage alloc] init];
        downLoadImge.delegate=self;
        [downLoadImge getImage:[self.allUrlArray objectAtIndex:self.initialImageViewCounter]];
    }
    @catch (NSException *e) {
        NSLog(@"callDownloadImageAPI exception %@",[e description]);
        [HUD hide:YES];        
    }
    [pool release];
}

This method download 1 image at a time and send UIImage to its delegate

//Implementation of DownloadImage.h and .m

    @protocol DownloadImageDelegate
    @required
    - (void)messageFormServerWithImage:(UIImage*)imageFromSever;
    - (void)gettingImageFailed :(NSString*)errorDesc;
    @end



        @interface DownloadImage : NSObject

        @property(strong) NSURLConnection*                       connection;
        @property(weak) id<DownloadImageDelegate>                delegate;
        @property(strong) NSMutableData*                         data;

        -(void)getImage:(NSString *)imageUrl;

//DownloadImage.m

-(void)getImage:(NSString *)imageUrl{
    @autoreleasepool {

        [[NSURLCache sharedURLCache] removeAllCachedResponses];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:imageUrl]cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];
    self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    }
}

- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection {
    @autoreleasepool {

    NSLog(@"connectionDidFinishLoading");
    self.connection=nil;
    if( self.data == nil) {
        return;
    }

//  NSString* jsonStr = [[NSString alloc] initWithData:self.data encoding:NSASCIIStringEncoding];
    UIImage *img=[UIImage imageWithData:self.data];
//  NSArray *messages_json = [parser objectWithString:jsonStr error:nil];
    [self.delegate messageFormServerWithImage:img];
    self.data = nil;
    img= nil;
    }
}

Other delegates of NSUrlConnections are implemented but I am not putting it here . Once this image is returned i am setting this image to scrollview and displaying it and deleting the previous image from scrollview.

More Info:-

Just to verify i commented out setting image to scrollview and just downloaded images on each swipe but still it crashes around 30 images

Surprisingly I am using same class DownloadImage.h and .m to download image at other places in the same work and it work awesome even with 500images .

I am testing in iPod Touch and I checked the memory utilised remain between 12-14mb(never exceed this)

Please help me out guys,let me know if you need more detail.

Abhinandan Sahgal
  • 1,076
  • 1
  • 13
  • 27
  • do you store the images? or just show them when the user swipe? If it's the second, take a look at asyncImageView, it's a ImageView replacement that show the images asyncly and caches them if you want. – jcesarmobile Mar 08 '13 at 09:00
  • If you're using ARC, you shouldn't be using NSAutoReleasePool. Instead use @autoreleasepool. – occulus Mar 08 '13 at 09:02
  • For more info, see http://stackoverflow.com/questions/9086913/objective-c-why-is-autorelease-autoreleasepool-still-needed-with-arc – occulus Mar 08 '13 at 09:02
  • @jcsear:-NO i donot store images,just downlaod on demand and delete if that part is not visible.I can look for async image view but the problem is there are lot of other things to be done with this which is not there in async image view like i have to pinch zoom etc so i have a spearate class create for that. – Abhinandan Sahgal Mar 08 '13 at 09:03
  • @occulus :-I am using arc for all the classes except one class where you saw NSAUtoreleasepool. – Abhinandan Sahgal Mar 08 '13 at 09:04

1 Answers1

1

Its crashing because all the images are being stored in virtual memory, you need to be caching them and then loading them back into memory when the user actually views them.

Try also setting your image objects to nil after they have been cached or are not needed.

In your class I would also recommend using the didReceiveMemoryWarning method and release some of your images from memory when this is called.

shoughton123
  • 4,255
  • 3
  • 21
  • 23
  • Thanks for the answer shoughton123 . I agree it may be in virtual memory.But for your answer provided,there is a doubt.Even to cache the image i will need to download atleast for the first time,right and after that i am caching it and loading from cache still the problem persists. On swipe itself i am deleting all the other images except the visible one,so it should not even reach didReceiveMemoryWarning – Abhinandan Sahgal Mar 09 '13 at 14:34