简体   繁体   English

UIImagePickerController内存泄漏Xcode 9在Swift 4中

[英]UIImagePickerController Memory Leak Xcode 9 in Swift 4

In my application I found a memory leak when I used the UIImagePickerController , I thought it was my application, but searching for a solution I found an Apple's sample and I also found that this sample has the same memory leak. 在我的应用程序中,当我使用UIImagePickerController ,我发现内存泄漏,我认为这是我的应用程序,但是在寻找解决方案时,我发现了Apple的样本,并且我还发现此示例具有相同的内存泄漏。

You can find the example in the following URL. 您可以在以下URL中找到该示例。

https://developer.apple.com/library/content/samplecode/PhotoPicker/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010196 https://developer.apple.com/library/content/samplecode/PhotoPicker/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010196

According to the UIImagePickerController documentation: 根据UIImagePickerController文档:

https://developer.apple.com/documentation/uikit/uiimagepickercontroller https://developer.apple.com/documentation/uikit/uiimagepickercontroller

In point 5, thy said that you have to dismiss the image picker using your delegate object, in the Apple's sample the UIImagePickerDelegate is doing the dismiss. 在第5点,你说你必须使用你的委托对象解雇图像选择器,在Apple的样本中, UIImagePickerDelegate正在进行解散。

The issue is that the memory leak is wasting approximately 21 MB of memory when you select an image and work with it. 问题是当您选择图像并使用它时,内存泄漏会浪费大约21 MB的内存。

Used Memory without Memory Leak 使用的内存没有内存泄漏

在此输入图像描述

Used Memory with Memory Leak 使用内存泄漏的内存

在此输入图像描述

Memory Leak 内存泄漏

在此输入图像描述

This is the code to present the UIImagePickerController : 这是呈现UIImagePickerController的代码:

@IBAction func showImagePickerForPhotoPicker(_ sender: UIBarButtonItem) {
    showImagePicker(sourceType: UIImagePickerControllerSourceType.photoLibrary, button: sender)
}

fileprivate func showImagePicker(sourceType: UIImagePickerControllerSourceType, button: UIBarButtonItem) {
    // If the image contains multiple frames, stop animating.
    if (imageView?.isAnimating)! {
        imageView?.stopAnimating()
    }
    if capturedImages.count > 0 {
        capturedImages.removeAll()
    }

    imagePickerController.sourceType = sourceType
    imagePickerController.modalPresentationStyle =
        (sourceType == UIImagePickerControllerSourceType.camera) ?
            UIModalPresentationStyle.fullScreen : UIModalPresentationStyle.popover

    let presentationController = imagePickerController.popoverPresentationController
    presentationController?.barButtonItem = button   // Display popover from the UIBarButtonItem as an anchor.
    presentationController?.permittedArrowDirections = UIPopoverArrowDirection.any

    if sourceType == UIImagePickerControllerSourceType.camera {
        // The user wants to use the camera interface. Set up our custom overlay view for the camera.
        imagePickerController.showsCameraControls = false

        // Apply our overlay view containing the toolar to take pictures in various ways.
        overlayView?.frame = (imagePickerController.cameraOverlayView?.frame)!
        imagePickerController.cameraOverlayView = overlayView
    }

    present(imagePickerController, animated: true, completion: {
        // Done presenting.
    })
}

And this is the code in the delegate to dismiss the UIImagePickerController : 这是委托中解除UIImagePickerController的代码:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    let image = info[UIImagePickerControllerOriginalImage]
    capturedImages.append(image as! UIImage)

    if !cameraTimer.isValid {
        // Timer is done firing so Finish up until the user stops the timer from taking photos.
        finishAndUpdate()
    } else {
        dismiss(animated: true, completion: nil)
    }
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    dismiss(animated: true, completion: {
        // Done cancel dismiss of image picker.
    })
}

fileprivate func finishAndUpdate() {
    dismiss(animated: true, completion: { [weak self] in
        guard let `self` = self else {
            return
        }

        if `self`.capturedImages.count > 0 {
            if self.capturedImages.count == 1 {
                // Camera took a single picture.
                `self`.imageView?.image = `self`.capturedImages[0]
            } else {
                // Camera took multiple pictures; use the list of images for animation.
                `self`.imageView?.animationImages = `self`.capturedImages
                `self`.imageView?.animationDuration = 5    // Show each captured photo for 5 seconds.
                `self`.imageView?.animationRepeatCount = 0   // Animate forever (show all photos).
                `self`.imageView?.startAnimating()
            }

            // To be ready to start again, clear the captured images array.
            `self`.capturedImages.removeAll()
        }
    })
}

I'm still looking for a solution, any help will be appreciated. 我仍在寻找解决方案,任何帮助将不胜感激。

I had the same issue. 我遇到过同样的问题。 So did a ton of other people. 其他人也是如此。 Dating back to 2008. Pretty crazy. 可以追溯到2008年。非常疯狂。

Unfortunately, the best answer I could find was to use a singleton, which sucks. 不幸的是,我能找到的最好的答案是使用单身,这很糟糕。 [ie Intentionally retain an instance of UIImagePickerController so you just access that every single time you want to select an image.] This is what others have suggested. [ie故意保留UIImagePickerController的一个实例,这样你就可以在每次想要选择图像时访问它。]这是其他人的建议。

Further, I just spent an hour writing this answer with code that uses a singleton, and I just could not avoid a memory leak [although I thought I had for a second]. 此外,我只花了一个小时用使用单例的代码编写这个答案,我无法避免内存泄漏[虽然我以为我有一秒钟]。 Maybe I'm just doing it incorrectly - feel free to try. 也许我只是做错了 - 随意尝试。 But I won't post my dysfunctional code as an answer. 但我不会发布我的功能失调的代码作为答案。

The best answer [which is how I solved my problem] is to use a third party pod/library. 最好的答案[我解决问题的方法]是使用第三方pod /库。 I used ImagePicker, and it is quick, fast, FREE, beautiful, and NO memory leaks! 我使用了ImagePicker,它快速,快速,免费,漂亮,并且没有内存泄漏! [MIT License] [麻省理工学院执照]

Check it out here: https://github.com/hyperoslo/ImagePicker 在这里查看: https//github.com/hyperoslo/ImagePicker

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

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