【问题标题】:memory leaks issue while saving images to directory将图像保存到目录时出现内存泄漏问题
【发布时间】:2018-07-04 01:34:55
【问题描述】:

请试着理解我的问题。 我正在从电话库中挑选图像并保存到文档目录中。但是当我选择大量图像时,使用的内存逐渐增加并达到 400 mb 以上,然后我的应用程序崩溃了。请问如果有人可以解决我的问题,我该怎么办?我是目标 C 的新手。任何回应将不胜感激。 这是我的代码

当拣货员完成拣货时

- (void)agImagePickerController:(AGImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info  {
[self ShowLoadingView:@"Files Are Loading...."];
[self performSelectorInBackground:@selector(saveAllSelectedImages:) withObject:info];}

然后我将图像保存到目录

-(void) saveAllSelectedImages:(NSArray*)imagesArray{

for (int i=0; i<imagesArray.count; i++) {

    ALAsset *asset = [imagesArray objectAtIndex:i];
    ALAssetRepresentation *alassetRep = [asset defaultRepresentation];
    NSDate *currentDate = [NSDate date];
    NSString* DucPath = [[AppDelegate GetDocumentDirectoryPath] stringByAppendingPathComponent:@"Media"];
    if (![[NSFileManager defaultManager] fileExistsAtPath:DucPath])
        [[NSFileManager defaultManager] createDirectoryAtPath:DucPath withIntermediateDirectories:NO attributes:nil error:nil];

    if ([[asset valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo])
    {



        long long DataSize = [alassetRep size];
        Byte *buffer = (Byte*)malloc(DataSize);
        NSUInteger buffered = (NSUInteger)[alassetRep getBytes:buffer fromOffset:0.0 length:alassetRep.size error:nil];
        NSData *videoData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];

        NSString* newVideoName = [NSString stringWithFormat:@"video_%d_%d.mov",(int)currentDate,i];
        NSString* newVideoPath = [DucPath stringByAppendingPathComponent:newVideoName];
        [videoData writeToFile:newVideoPath atomically:YES];

        [pImageMediaArray addObject:newVideoName];
    }
    else
    {
        UIImage *image = [UIImage imageWithCGImage:[alassetRep fullResolutionImage]];

        /************************************Full Resolution Images ******************************************/

        NSData *imageData = UIImageJPEGRepresentation(image, 0.8);
        image = nil;

        NSString *originalPath = [NSString stringWithFormat:@"IMAGE_%d_%d.jpg",(int)currentDate,i];
        NSString* pImagePath = [DucPath stringByAppendingPathComponent:originalPath];

        [imageData writeToFile:pImagePath atomically:YES];

        [pImageMediaArray addObject:originalPath];

    }
    /************************************Low Resolution Images ******************************************/
    UIImage *image = [UIImage imageWithCGImage:[alassetRep fullResolutionImage]];
    UIImage *thumbImage = [self imageWithImage:image scaledToSize:CGSizeMake(50, 50)];

    NSData *thumbImageData = UIImageJPEGRepresentation(thumbImage, 0.8);


    NSString *thumbOriginalPath = [NSString stringWithFormat:@"SMALL_IMAGE_%d_%d.jpg",(int)currentDate,i];
    NSString* thumbImagePath = [DucPath stringByAppendingPathComponent:thumbOriginalPath];
    NSLog(@"Image path At Save Time:%@",thumbImagePath);
    [thumbImageData writeToFile:thumbImagePath atomically:YES];

    [pMediaArray addObject:thumbOriginalPath];
}

[appDelegate setPMediaArray:pImageMediaArray];


[pGridView reloadData];
imagesArray = nil;
[imagesArray release];
[pImageMediaArray release];
[self performSelectorOnMainThread:@selector(closeLoadindView) withObject:nil waitUntilDone:YES];}

【问题讨论】:

    标签: objective-c ios7


    【解决方案1】:
    Byte *buffer = (Byte*)malloc(DataSize);
    

    没有被释放?

    【讨论】:

    • 这可能是原因,但它仅在选择视频时运行。但我只选择图像..
    • 我建议使用NSMutableData* videoData = [NSMutableData dataWithCapasity:DataSize]; Byte *buffer = [videoData mutableBytes]; [videoData setLength:buffered];
    • OP 使用 -dataWithBytesNoCopy:length:freeWhenDone: 并将 freeWhenDone: 参数设置为 YES。所以NSData 实例负责释放缓冲区。 developer.apple.com/library/ios/documentation/cocoa/reference/…:
    【解决方案2】:

    我遇到了完全相同的问题。对我有用的是在保存图像时使用自动释放池块。这将释放保留计数,垃圾回收将适当地释放内存,而不是将这些对象保留在内存中,直到包含循环完成运行。

    示例:在您用于保存图像的方法中,添加如下所示的代码:

    @autoreleasepool {
        NSString *filePath = [[NSArray arrayWithObjects:self.imagePath, @"/", GUID, @".png", nil] componentsJoinedByString:@""];
        NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];
        BOOL res = [imageData writeToFile:filePath atomically:YES];
        imageData = nil;
    }
    

    【讨论】:

      【解决方案3】:

      您需要为在后台执行的任务添加autoreleasepool。上面代码中saveAllSelectedImages的内容要写在autoreleasepool里面,否则内存不会被释放。

      【讨论】:

      • 你能给我举个例子吗?
      • @autoreleasepool { [self performSelectorInBackground:@selector(saveAllSelectedImages:) withObject:info]; } 像这样?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-19
      • 2020-09-21
      • 1970-01-01
      • 2016-07-28
      相关资源
      最近更新 更多