Hussain Chhatriwala
Hussain Chhatriwala

Reputation: 849

Due to heavy images stored in document directory app is receiving memory warning. And app get crashed

I am working on a app which is highly dependent on saving images in document directory and retrieving it and displaying it on screen.

As soon as I display 5 -6 images in collection view the ap gets slowed up and suddenly receives memory warning and stopes functioning and app crashes.

I am using following code to display data

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
             cellForItemAtIndexPath:(NSIndexPath *)indexPath

{ DocumentCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"DocumentCollectionViewCell" forIndexPath:indexPath];

if(cell!=nil){
    cell  = [collectionView dequeueReusableCellWithReuseIdentifier:@"DocumentCollectionViewCell" forIndexPath:indexPath];

}
Documents *documents = [arrTableData objectAtIndex:indexPath.row];
cell.imgView.contentMode = UIViewContentModeScaleAspectFit;
cell.imgContentView.layer.cornerRadius = 4.0f;
cell.imgContentView.layer.masksToBounds = YES;
cell.imgContentView.layer.borderColor = [UIColor lightGrayColor].CGColor;
cell.imgContentView.layer.borderWidth = .4f;

[cell.btnLockOrUnlock addTarget:self action:@selector(lockAction:) forControlEvents:UIControlEventTouchUpInside];
cell.btnLockOrUnlock.tag = indexPath.row;
// set count
cell.lblCount.text =[NSString stringWithFormat:@"%@ Page",documents.imageCount];
cell.imgView.layer.cornerRadius = 6.0f;
cell.imgView.layer.masksToBounds = YES;
newDocDate = documents.issueDate;
// set image
NSString * passcode = documents.passcode;
if(passcode.length>3){
    cell.bluredView.hidden = NO;
    [cell.btnLockOrUnlock setImage:[UIImage imageNamed:@"lockWhite"] forState:UIControlStateNormal];
}
else{
    [cell.btnLockOrUnlock setImage:[UIImage imageNamed:@"unlockWhite"] forState:UIControlStateNormal];
    cell.bluredView.hidden = YES;
}

[cell.btnSelect addTarget:self action:@selector(cellSelectAction:) forControlEvents:UIControlEventTouchUpInside];
cell.btnSelect.tag = indexPath.row;
NSString *title = documents.title;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Fetch path for document directory
NSString * docDirectoryPath = (NSMutableString *)[documentsDirectory stringByAppendingPathComponent:title];

//-----------------path of document ------------------

NSString *filePath = [docDirectoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"image%d.png",0]];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
int i =0;
while (!fileExists) {
    filePath = [docDirectoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"image%d.png",i]];
    fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
    i++;
}
CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef) [NSURL fileURLWithPath:filePath], NULL);
// Create thumbnail options
CFDictionaryRef options = (__bridge CFDictionaryRef) @{
                                                       (id) kCGImageSourceCreateThumbnailWithTransform : @YES,
                                                       (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
                                                       (id) kCGImageSourceThumbnailMaxPixelSize : @(cell.imgView.frame.size.height)
                                                       };
// Generate the thumbnail
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
UIImage* uiImage = [[UIImage alloc] initWithCGImage:thumbnail];  //<--CRASH
cell.DocName.text = documents.docName;


//-----------------display image on cell------------------


cell.imgView.image = uiImage;
uiImage = nil;
uiImage = NULL;
documents = nil;
documents = nil;
title = nil;
thumbnail = nil;
src = nil;
options = nil;
filePath = nil;
paths = nil;
documentsDirectory = nil;
docDirectoryPath = nil;
return cell;

}

I am setting all the objects to nil.

I am using following code to save images

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Fetch path for document directory
folderName = (NSMutableString *)[documentsDirectory stringByAppendingPathComponent:folderName];

NSData *pngData = UIImagePNGRepresentation(arrImages[i]); NSString *filePath = [folderName stringByAppendingPathComponent:[NSString stringWithFormat:@"image%d.png",i]]; //Add the file name [pngData writeToFile:filePath atomically:YES]; //Write the file

I save the original image from camera without any compression or resizing in document directory.

I am unable to understand the problem please help.

Thanks in advance.

Upvotes: 2

Views: 621

Answers (1)

Andrea
Andrea

Reputation: 26383

It seems to be due to memory leaks, check your app using instruments and lacks tool.

CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef) [NSURL fileURLWithPath:filePath], NULL);
// Create thumbnail options
CFDictionaryRef options = (__bridge CFDictionaryRef) @{
                                                       (id) kCGImageSourceCreateThumbnailWithTransform : @YES,
                                                       (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
                                                       (id) kCGImageSourceThumbnailMaxPixelSize : @(cell.imgView.frame.size.height)
                                                       };
// Generate the thumbnail
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
UIImage* uiImage = [[UIImage alloc] initWithCGImage:thumbnail];  //<--CRASH

CFFoundation objects follow similar memory management rules (If you create or copy you need to release it) of Obj-C before ARC (ARC doesn't manage core foundation objects).
In the code you have shown I see that you aren't releasing the CGImageRef and the CGImageSourceRef, this create two leaks and probably the crash.
Collection view cells are recycled thus the number of image opened in memory are basically the number of cells you are seeing on screen they should be the cause of your crash.

Upvotes: 1

Related Questions