由于存储在文档目录中的大量图像,应用程序正在接收内存警告。应用程序崩溃了
Due to heavy images stored in document directory app is receiving memory warning. And app get crashed
我正在开发一个高度依赖于在文档目录中保存图像并检索图像并将其显示在屏幕上的应用程序。
一旦我在 collection 视图中显示 5 -6 张图像,应用程序就会变慢并突然收到内存警告并停止运行和应用程序崩溃。
我正在使用以下代码显示数据
-(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;
}
我将所有 objects 设置为零。
我正在使用以下代码保存图像
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]]; //添加文件名
[pngData writeToFile:filePath atomically:YES]; //写入文件
我在文档目录中保存了来自相机的原始图像,没有任何压缩或调整大小。
我无法理解问题,请帮助。
提前致谢。
好像是内存泄露,用instruments检查你的app,缺少工具
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 对象在 ARC () 之前遵循与 Obj-C 类似的内存管理规则(如果创建或复制则需要释放它)()。
在您展示的代码中,我看到您没有发布 CGImageRef
和 CGImageSourceRef
,这会造成两次泄漏,并可能导致崩溃。
集合视图单元格被回收,因此在内存中打开的图像数量基本上是您在屏幕上看到的单元格数量,它们应该是您崩溃的原因。
我正在开发一个高度依赖于在文档目录中保存图像并检索图像并将其显示在屏幕上的应用程序。
一旦我在 collection 视图中显示 5 -6 张图像,应用程序就会变慢并突然收到内存警告并停止运行和应用程序崩溃。
我正在使用以下代码显示数据
-(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;
}
我将所有 objects 设置为零。
我正在使用以下代码保存图像
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]]; //添加文件名 [pngData writeToFile:filePath atomically:YES]; //写入文件
我在文档目录中保存了来自相机的原始图像,没有任何压缩或调整大小。
我无法理解问题,请帮助。
提前致谢。
好像是内存泄露,用instruments检查你的app,缺少工具
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 对象在 ARC (
在您展示的代码中,我看到您没有发布 CGImageRef
和 CGImageSourceRef
,这会造成两次泄漏,并可能导致崩溃。
集合视图单元格被回收,因此在内存中打开的图像数量基本上是您在屏幕上看到的单元格数量,它们应该是您崩溃的原因。