OGeek|极客世界-中国程序员成长平台

标题: ios - 由于存储在文档目录应用程序中的大量图像正在接收内存警告。应用程序崩溃了 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 15:56
标题: ios - 由于存储在文档目录应用程序中的大量图像正在接收内存警告。应用程序崩溃了

我正在开发一个高度依赖于将图像保存在文档目录中并检索它并将其显示在屏幕上的应用程序。

当我在 Collection View 中显示 5 -6 图像时,应用程序会变慢并突然收到内存警告并停止运行并且应用程序崩溃。

我正在使用以下代码来显示数据

-(UICollectionViewCell *)collectionViewUICollectionView *)collectionView
             cellForItemAtIndexPathNSIndexPath *)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 actionselector(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 actionselector(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;

}

我将所有对象设置为零。

我正在使用以下代码保存图像

 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 = [文件夹名称 stringByAppendingPathComponent:[NSString stringWithFormat"image%d.png",i]];//添加文件名 [pngData writeToFile:filePath atomically:YES];//写入文件

我将相机中的原始图像保存在文档目录中,没有进行任何压缩或调整大小。

我无法理解问题,请帮忙。

提前致谢。



Best Answer-推荐答案


好像是内存泄漏,用instrument检查你的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 (ARC doesn't manage core foundation objects) 之前的 Obj-C 类似的内存管理规则(如果创建或复制,则需要释放它)。
在您显示的代码中,我看到您没有释放 CGImageRefCGImageSourceRef,这会造成两次泄漏,并可能导致崩溃。
Collection View 单元格被回收,因此在内存中打开的图像数量基本上就是您在屏幕上看到的单元格数量,它们应该是导致崩溃的原因。

关于ios - 由于存储在文档目录应用程序中的大量图像正在接收内存警告。应用程序崩溃了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36519694/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://sqlite.in/) Powered by Discuz! X3.4