Reputation: 1121
My app is terminating due to memory pressure at a certain point in the app's use, and I have isolated the problem down to one chunk of code that is causing the problem.
I'll copy the code below ( I have tested by commenting out this code and running the app , and the app runs fine).
What I am trying to do here is : I am reading an RSS feed , getting URL of an image and displaying it in a tableView cell. The code below is from the cellForRowAtIndexPath.
// 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:imgSrcString] == true)
{
cell.cellImageView.image = [[ImageCache sharedImageCache] GetImage:imgSrcString];
} else {
cell.cellImageView.image = [UIImage imageNamed:@"NoImage_Small"];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
// Now, we can’t cancel a block once it begins, so we’ll use associated objects and compare
// index paths to see if we should continue once we have a resized image.
objc_setAssociatedObject(cell,
kIndexPathAssociationKey,
indexPath,
OBJC_ASSOCIATION_RETAIN);
dispatch_async(queue, ^{
NSData * imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imgSrcString]];
UIImage *image = [UIImage imageWithData:imageData];
//UIImage *resizedImage = [image scaleToSize:CGSizeMake(71.0f,71.0f)] ; //[UIImage resizeImage];
dispatch_async(dispatch_get_main_queue(), ^{
NSIndexPath *cellIndexPath =
(NSIndexPath *)objc_getAssociatedObject(cell, kIndexPathAssociationKey);
if(image){
if ([indexPath isEqual:cellIndexPath]) {
[[cell cellImageView] setImage:image];
[[ImageCache sharedImageCache] AddImage:imgSrcString :image];
}
}
// [[ImageCache sharedImageCache] AddImage:[imgSrcString stringByAppendingString:@"bigImage"] :image];
});
});
}
Any help to point me in the right direction would be greatly appreciated. Thanks for your time !
Upvotes: 0
Views: 299
Reputation: 1121
I think the main issue was not multi threading in the code, but the fact that I was downloading big images and storing them in the ImageCache, which was quickly becoming bloated and was causing the crash. What I did to resolve this was to resize the image after it downloaded and then add the smaller image in the cache ( I am using it as a thumbnail image anyway, so dont really need the big image to be stored). That dramatically reduced the number of crashes. Hope it helps someone in similar situation.
Upvotes: 0
Reputation: 4614
Regarding this issue i have surfed. By the way,in some blogs they mentioned by default NSURLConnection contains cache that will be not clear at all. That may be the reason for the crash. So Try to use ASIHTTPRequest http://allseeing-i.com/ASIHTTPRequest/ then you never feel the memory warning regarding image download.
use this code for ASIHTTPRequest integration (after adding the sdk files)
-(void)resetNetworkQueue
{
// initialising network queue.
self.networkQueue =[[ASINetworkQueue alloc]init];
[self.networkQueue setRequestDidFinishSelector:@selector(mediaDownloadCompleted:)];
[self.networkQueue setRequestDidFailSelector:@selector(mediaDownloadFailed:)];
[self.networkQueue setRequestDidStartSelector:@selector(mediaDownloadStarted:)];
[self.networkQueue setQueueDidFinishSelector:@selector(networkQueueCompletedProcess:)];
[self.networkQueue setMaxConcurrentOperationCount:10];
[self.networkQueue setShouldCancelAllRequestsOnFailure:NO];
[self.networkQueue setDelegate:self];
}
-(void)createDownloadRequest
{
//Adding request in network queue.
self.request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:imageURL]];
[self.request setDownloadDestinationPath:downloadDestinationPath];
[self.request setDelegate:self];
[self.request setAllowResumeForFileDownloads:YES];
[self.request setTimeOutSeconds:30];
[self.networkQueue addOperation:self.request];
[self.request setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:homeInfo,@"FloorPlanInfo",imageType,@"ImageType", nil]];
}
- (void)mediaDownloadStarted:(ASIHTTPRequest *)request
{
//Fire when request started.
}
- (void)mediaDownloadCompleted:(ASIHTTPRequest *)request
{
//Fire when request completed.
}
- (void)mediaDownloadFailed:(ASIHTTPRequest *)request
{
//Fire when request Failed to download.
}
Upvotes: 1