简体   繁体   English

从照片库导入图像时出现内存泄漏

[英]memory leak when importing images from photo library

i am having a memory problem with importing photos from the camera roll. 我从相机胶卷导入照片时遇到内存问题。 I am using storyboard and ARC (automatic reference counting). 我正在使用情节提要和ARC(自动引用计数)。 when I import the 3rd or 4th photo the app crashes, and in fact instruments shows under free physical memory that there is no memory left. 当我导入第三张或第四张照片时,应用程序崩溃,并且实际上仪器显示出可用的物理内存下没有剩余的内存。 I tried using @autoreleasepools but it does not seem to work: 我尝试使用@autoreleasepools,但它似乎不起作用:

- (void)viewDidLoad {
@autoreleasepool {
[super viewDidLoad];

UIBarButtonItem *cameraButton = [[UIBarButtonItem alloc]
                                 initWithTitle:@"Camera"
                                 style:UIBarButtonItemStyleBordered
                                 target:self
                                 action:@selector(useCamera:)];

UIBarButtonItem *cameraRollButton = [[UIBarButtonItem alloc] 
                                     initWithTitle:@"Camera Roll"
                                     style:UIBarButtonItemStyleBordered
                                     target:self
                                     action:@selector(useCameraRoll:)];
NSArray *items = [NSArray arrayWithObjects: cameraButton,
                  cameraRollButton, nil];
[toolbar setItems:items animated:NO];

mouseMoved = 0;

}}

 - (IBAction) useCamera: (id)sender
 {
if ([UIImagePickerController isSourceTypeAvailable:
     UIImagePickerControllerSourceTypeCamera])
{
    UIImagePickerController *imagePicker =
    [[UIImagePickerController alloc] init];
    imagePicker.delegate = self;
    imagePicker.sourceType =
    UIImagePickerControllerSourceTypeCamera;
    imagePicker.mediaTypes = [NSArray arrayWithObjects:
                              (NSString *) kUTTypeImage,
                              nil];
    imagePicker.allowsEditing = NO;
    [self presentModalViewController:imagePicker
                            animated:YES];

    newMedia = YES;

    }else{
    NSLog(@"Camera is not available");
    UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:@"Important message" message:@"Unfortunately the camera is not available on your device." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
    [alert1 show];
}

}

 - (IBAction) useCameraRoll: (id)sender
{
@autoreleasepool {

    if ([self.popoverController isPopoverVisible]) {
    [self.popoverController dismissPopoverAnimated:YES];

    } else{

    }{
    if ([UIImagePickerController isSourceTypeAvailable:
         UIImagePickerControllerSourceTypeSavedPhotosAlbum])
    {
        @autoreleasepool {

        UIImagePickerController *imagePicker =
        [[UIImagePickerController alloc] init];

        imagePicker.delegate = self;
        imagePicker.sourceType =
        UIImagePickerControllerSourceTypePhotoLibrary;
        imagePicker.mediaTypes = [NSArray arrayWithObjects:
                                  (NSString *) kUTTypeImage,
                                  nil];

        imagePicker.allowsEditing = YES;

        self.popoverController = [[UIPopoverController alloc]
                                  initWithContentViewController:imagePicker];
        }
        popoverController.delegate = self;

        [self.popoverController 
         presentPopoverFromBarButtonItem:sender
         permittedArrowDirections:UIPopoverArrowDirectionUp
         animated:YES];


        newMedia = NO;
    }}
}
 }

-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [self.popoverController dismissPopoverAnimated:true];
    @autoreleasepool {


NSString *mediaType = [info
                       objectForKey:UIImagePickerControllerMediaType];

    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
    UIImage *image = [info
                      objectForKey:UIImagePickerControllerOriginalImage];

    image1.image = image;
    if (newMedia)
        UIImageWriteToSavedPhotosAlbum(image,
                                       self,  
                                          @selector(image:finishedSavingWithError:contextInfo:),
                                       nil);
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{
    // Code here to support video if enabled
}}
}

-(void)image:(UIImage *)image
finishedSavingWithError:(NSError *)error
 contextInfo:(void *)contextInfo
{
if (error) {
    UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle: @"Save failed"
                          message: @"Failed to save image"\
                          delegate: nil
                          cancelButtonTitle:@"OK"
                          otherButtonTitles:nil];
    [alert show];
}
}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{

}

please help!! 请帮忙!! thanks in advance. 提前致谢。

Have same issue. 有同样的问题。 Using 2-3 MB for each new item created. 每个创建的新项目使用2-3 MB。 Responsible caller = CGDataProviderCreateWithCopyOfData 负责的呼叫者= CGDataProviderCreateWithCopyOfData

Had to set 必须设置

imagePicker.allowsEditing = NO;

It seems that when using editing the image, this does not release properly. 似乎在使用编辑图像时,此图像无法正确释放。

How does image1.image handle ownership. image1.image如何处理所有权。

Use Heapshot to find where/how the memory is lost: For HowTo use Heapshot to find memory creap, see: bbum blog 使用Heapshot查找内存丢失的位置/方式:有关如何使用Heapshot查找内存不足的信息,请参阅: bbum博客

Basically there method is to run Instruments allocate tool, take a heapshot, run an intuition of your code and another heapshot repeating 3 or 4 times. 基本上,有一种方法是运行Instruments分配工具,进行一次堆快照,运行代码的直觉以及另一个重复3或4次的堆快照。 This will indicate memory that is allocated and not released during the iterations. 这将指示在迭代期间已分配但未释放的内存。

To figure out the results disclose to see the individual allocations. 要弄清楚结果,请公开查看各个分配。

If you need to see where retains, releases and autoreleases occur for an object use instruments: 如果需要查看对象的保留,释放和自动释放位置,请使用工具:

Run in instruments, in Allocations set "Record reference counts" on on (you have to stop recording to set the option). 在乐器中运行,在分配中将“记录参考计数”设置为开(必须停止记录才能设置该选项)。 Cause the picker to run, stop recording, search for there ivar (datePickerView), drill down and you will be able to see where all retains, releases and autoreleases occurred. 使选择器运行,停止记录,在其中搜索ivar(datePickerView),向下钻取,您将能够看到发生了所有保留,释放和自动释放的位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM