PHPickerViewController causes memory link

I want to pick an image with PHPickerViewController. But this causes to memory link. Can anyone help me with this issue?(

I created ImagePickerManager and I'm using it on ViewController below.

P.s: I didn't get a leak when writing the same code with UIImagePickerViewController.

import Foundation
import Photos
import PhotosUI

class ImagePickerManager: NSObject {

  // MARK: Variables
  var accessType: PHAccessLevel = .addOnly

  var pickerViewController = PHPickerViewController(configuration: PHPickerConfiguration())
  //var viewController: UIViewController?
  var pickImageCallback : ((UIImage) -> ())?;

  // MARK: Init
  override init() {
    super.init()

    setupPhotoPicker()
    setupPhotoLibrary(accessType)
  }
//  convenience init(
//    viewController: UIViewController,
//    accessType: PHAccessLevel = .addOnly) {
//      self.init()
//
//      self.viewController = viewController
//      setupPhotoLibrary(accessType)
//      setupPhotoPicker()
//    }

  // MARK: Setup
  private func setupPhotoLibrary(_ accessType: PHAccessLevel) {
    self.checkAuthorizationStatusForPhotoLibrary()
    self.accessType = accessType
  }

  private func setupPhotoPicker() {
    pickerViewController.delegate = self
  }

  // MARK: Present PickerController
  func presentPHPicker(_ viewContr: UIViewController,_ callback: @escaping ((UIImage) -> ())) {
    pickImageCallback = callback
   // self.viewController = viewContr
    viewContr.present(pickerViewController, animated: true)
  }

  // MARK: Checking status of Photo library access
  func checkAuthorizationStatusForPhotoLibrary() {
    switch PHPhotoLibrary.authorizationStatus(for: accessType) {
    case .authorized: break
    case .notDetermined:
      self.requestAuthorizationForPhotoLibrary()
    case .denied:
      self.showAccessDeniedMessage()
    default: return
    }
  }

  // MARK: Request to Access Photo Library
  func requestAuthorizationForPhotoLibrary () {
    PHPhotoLibrary.requestAuthorization(for: accessType) { status in
      switch status {
      case .authorized:
        print("Access granted")
      case .denied: break
      case .notDetermined: break
      default: return
      }
    }
  }

  // MARK: Access Denied to do action
  private func showAccessDeniedMessage() {
    print("\n ShowAccessDeniedMessage \n")
  }
}

// MARK: - PHPickerViewControllerDelegate
extension ImagePickerManager: PHPickerViewControllerDelegate, UINavigationControllerDelegate {

  func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    picker.dismiss(animated: true, completion: nil)

    for result in results {
      result.itemProvider.loadObject(ofClass: UIImage.self, completionHandler: { (object, error) in
        if let image = object as? UIImage {
//          DispatchQueue.main.async {
            // Use UIImage
            self.pickImageCallback?(image)
//          }
        }
      })
    }
  }

}

/// -------- ViewController
let imageManager = ImagePickerManager()
  @objc func pressedButton() {
    imageManager.presentPHPicker(self) { image in
      print("something...")
    }
  }

You may have a retain cycle.

Have a look here to check: h t t p s : / / stablekernel.com/article/how-to-prevent-memory-leaks-in-swift-closures/

I see an important difference between your code and those from the keynote. In the keynote it's: completionHandler: { [weak self] (object, error) in while in your code it's completionHandler: { (object, error) in. I suppose, they explicitly added a weak reference to self to avoid memory leak.

PHPickerViewController causes memory link
 
 
Q