使用Instruments跟踪内存泄漏 Xcode5和iOS7

4

我开发了我的第一个应用程序,仍在学习中。昨天刚更新了Xcode 5,我的iPhone 5正在运行iOS 7.1。我现在正在努力理解Instruments工具以分析我的应用程序。我正在使用Instruments中的泄漏配置文件,并遇到了一些保留循环和泄漏问题,但我无法解决。非常感谢您能提供帮助,让我了解a)如何确定错误并b)我犯了什么错误以及如何避免。

在我的应用程序中,我正在使用相机拍照。当相机启动时,我点击屏幕对焦,这时我注意到Instruments中出现了泄漏。看起来在我的代码中没有保留循环(如果我理解得正确),但是却存在一个根泄漏,我不明白。

我正在使用ARC,因此在Instruments指向我代码的部分(下面的第2部分)中,我不需要释放“picker”。

CALayer Retain Cycle

  1. 如何处理保留循环?它不在我的代码中,但我仍然是原因吗?它是否源于“根泄漏”?如果我不负责,我该怎么办?

Root Leak

  1. 在此堆栈跟踪中,我的唯一代码不能帮助我理解泄漏的来源。Instruments指向的行是我的代码中的[picker dismissViewControllerAnimated:YES completion:nil];在我的imagePickerController:didFinishPickingMediaWithInfo:方法中。我将代码复制如下。
 - (void)imagePickerController:(UIImagePickerController *)picker
    didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *pickerImage = [info objectForKey:
                            UIImagePickerControllerOriginalImage];

    _imageView.image = pickerImage;

    [picker dismissViewControllerAnimated:YES completion:nil]; // <--- mem-leak
}

编辑 - 我创建UIImagePickerController的代码。

- (IBAction)snapPicture:(id)sender
{
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];

    // If the camera button was tapped AND we have a camera, use it...
    if ((sender == _cameraButton) && [UIImagePickerController
         isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    {
        [imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
    } else {
        [imagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
    }

    imagePicker.delegate = self;

    // bring up the image picker view
    [self presentViewController:imagePicker animated:YES completion:nil];
}

你能否发布一下创建 UIImagePickerController 的代码? - Austin
1
那么CAMBlurredSnapshotView是什么?我的意思是,这显然是问题的原因。这段代码是你从别处拿来的吗? - matt
@Austin - 我无法弄清楚如何在这里创建代码块。您可以在此处查看我创建UIImagePickerController的方法:http://pastebin.com/7s37iaFA - knarf
@matt - 我这里没有使用任何其他代码。我确实使用了GKImagePicker来裁剪图片,但是那段代码在这里没有被调用。我认为CAMBlurredSnapshotView是苹果的相机API的一部分。 - knarf
好答案。事实上,它如此出色,以至于我现在确信您无法或不应该对这个泄漏采取任何行动。就像你说的那样,它是内置的。 - matt
1
我向苹果提交了一个关于这个问题的错误报告,但很快就被退回了。所以他们知道这个问题;然而这并不意味着他们会尽快修复它。 - matt
1个回答

7

这是我的理论:你所遇到的显然是苹果自己代码中的一个漏洞(或缺陷),你能做的就是疯狂地笑一下,然后忘掉它。

为了验证我的理论,我运行了我自己编写的完全独立并在不同时间编写的代码。它几乎和你的代码做了相同的事情:让用户拍照,并将图像放入界面中。这是我的代码:

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch17p702takeAPicture/ch30p962takeAPicture/ViewController.m

我在Instruments中使用Leaks工具运行了我的代码,猜猜发生了什么?我看到了你看到的相同问题。

enter image description here

自然地,我随后在Stack Overflow上进行搜索,结果发现这都是老问题了。例如:

iOS5上的UIImagePickerController内存泄漏

甚至连苹果自己的示例代码,名为PhotoPicker(或使用UIImagePickerController选择图片和拍照),也存在相同的泄漏问题。

谢谢大家。我应该在搜索中包括UIImagePickerController。我正在包括CALayer并找到其他没有解决这个问题的内容。感谢您的时间和努力。我刚刚修复了一个不同的内存泄漏,其中我必须释放CFTypeRef,并且直到今天才意识到这一点。所以我想也许有关于图像选择器我没有理解的东西我错过了。再次感谢! - knarf
1
这是我书中关于CFTypeRef内存管理的讨论:http://www.apeth.com/iOSBook/ch12.html#_memory_management_of_cftyperefs - matt
@matt:那现在有解决方案吗?有人向苹果报告了这个 bug 吗?我运行了“SquareCam”演示应用程序,它也会偶尔崩溃。我的应用程序几分钟后也会崩溃... - Susim Samanta
@San 当然我已经报告了,特别是因为这个错误可以用苹果自己的代码演示。我的建议是尝试iOS 8。如果那里没有修复,请一定再次提交错误报告!顺便说一句,永远不要问“有人报告了吗?”只需报告即可!不要让别人替你工作,此外,报告越多越好(即使有人已经报告,也不要犹豫不决);苹果将报告视为投票。 - matt
@Matt 谢谢。我在尝试使用IOS8,但是CFNetwork还有更多其他问题。我无法运行我的应用程序。我有一个好奇心,其他应用程序如Snapchat是如何正常工作的?他们做了什么不同的事情吗? - Susim Samanta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接