内存泄漏 AlertController / UIImagePickerController
Memory Leak AlertController / UIImagePickerController
我有一个 class 可以从图库或相机中挑选照片。
我打开一个 alertController 并让您在画廊和相机之间进行选择。它还包含一个委托。如果我从图库中选择一张图片,我会发现仪器存在内存泄漏。如何改进代码以避免内存泄漏?谢谢!
class ImagePickerManager: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var imagePicker = UIImagePickerController()
weak var delegate: DelegatePhotohandler?
var viewController: UIViewController?
override init() {
super.init()
}
func pickImage<T:UIViewController>(viewController: T) {
self.viewController = viewController
let alertList = UIAlertController(title: NSLocalizedString("Load Picture", comment: "Picture alert Alertcontroller"), message: nil, preferredStyle: .actionSheet)
let cameraAction = UIAlertAction(title: "Camera", style: .default) {
UIAlertAction in self.openCamera()
alertList.dismiss(animated: true, completion: nil)
}
let galleryAction = UIAlertAction(title: "Gallery", style: .default) {
UIAlertAction in self.openGallery()
alertList.dismiss(animated: true, completion: nil)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) {
UIAlertAction in
alertList.dismiss(animated: true, completion: nil)
}
alertList.addAction(cameraAction)
alertList.addAction(galleryAction)
alertList.addAction(cancelAction)
viewController.present(alertList, animated: true, completion: nil)
}
private func openCamera() {
if(UIImagePickerController .isSourceTypeAvailable(.camera)) {
imagePicker.sourceType = .camera
imagePicker.delegate = self
self.viewController!.present(imagePicker, animated: true, completion: nil)
} else {
let warningAlert = UIAlertController(title: "Warning", message: "You do not have a camera", preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Okay", style: .cancel) {
UIAlertAction in
warningAlert.dismiss(animated: true, completion: nil)
}
warningAlert.addAction(cancelAction)
self.viewController!.present(warningAlert, animated: true, completion: nil)
}
}
private func openGallery() {
imagePicker.sourceType = .photoLibrary
imagePicker.delegate = self
self.viewController!.present(imagePicker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true, completion: nil)
guard let image = info[.originalImage] as? UIImage else {
print("Expected a dictionary containing an image, but was provided the following: \(info)")
return
}
delegate?.returnImage(image: image)
}
}
UIImagePickerController
泄漏是一个已知且非常古老的问题:
- UIImagePickerController Memory Leak
- Memory leak in UIImagePicker in iphone
解决方案基本上是将选取器的实例存储在单例中,并在需要时重用它(忽略选取器本身的小内存泄漏),或者使用不存在此问题的第三方图像选取器.
作为旁注,您的代码可以通过删除 viewController
属性 并将其添加为 openCamera
和 openGallery
中的参数来改进,如下所示:
self.openGallery(viewController: viewController)
// ...
private func openGallery<T:UIViewController>(viewController: T) {
imagePicker.sourceType = .photoLibrary
imagePicker.delegate = self
viewController.present(imagePicker, animated: true)
}
我有一个 class 可以从图库或相机中挑选照片。 我打开一个 alertController 并让您在画廊和相机之间进行选择。它还包含一个委托。如果我从图库中选择一张图片,我会发现仪器存在内存泄漏。如何改进代码以避免内存泄漏?谢谢!
class ImagePickerManager: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var imagePicker = UIImagePickerController()
weak var delegate: DelegatePhotohandler?
var viewController: UIViewController?
override init() {
super.init()
}
func pickImage<T:UIViewController>(viewController: T) {
self.viewController = viewController
let alertList = UIAlertController(title: NSLocalizedString("Load Picture", comment: "Picture alert Alertcontroller"), message: nil, preferredStyle: .actionSheet)
let cameraAction = UIAlertAction(title: "Camera", style: .default) {
UIAlertAction in self.openCamera()
alertList.dismiss(animated: true, completion: nil)
}
let galleryAction = UIAlertAction(title: "Gallery", style: .default) {
UIAlertAction in self.openGallery()
alertList.dismiss(animated: true, completion: nil)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) {
UIAlertAction in
alertList.dismiss(animated: true, completion: nil)
}
alertList.addAction(cameraAction)
alertList.addAction(galleryAction)
alertList.addAction(cancelAction)
viewController.present(alertList, animated: true, completion: nil)
}
private func openCamera() {
if(UIImagePickerController .isSourceTypeAvailable(.camera)) {
imagePicker.sourceType = .camera
imagePicker.delegate = self
self.viewController!.present(imagePicker, animated: true, completion: nil)
} else {
let warningAlert = UIAlertController(title: "Warning", message: "You do not have a camera", preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Okay", style: .cancel) {
UIAlertAction in
warningAlert.dismiss(animated: true, completion: nil)
}
warningAlert.addAction(cancelAction)
self.viewController!.present(warningAlert, animated: true, completion: nil)
}
}
private func openGallery() {
imagePicker.sourceType = .photoLibrary
imagePicker.delegate = self
self.viewController!.present(imagePicker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true, completion: nil)
guard let image = info[.originalImage] as? UIImage else {
print("Expected a dictionary containing an image, but was provided the following: \(info)")
return
}
delegate?.returnImage(image: image)
}
}
UIImagePickerController
泄漏是一个已知且非常古老的问题:
- UIImagePickerController Memory Leak
- Memory leak in UIImagePicker in iphone
解决方案基本上是将选取器的实例存储在单例中,并在需要时重用它(忽略选取器本身的小内存泄漏),或者使用不存在此问题的第三方图像选取器.
作为旁注,您的代码可以通过删除 viewController
属性 并将其添加为 openCamera
和 openGallery
中的参数来改进,如下所示:
self.openGallery(viewController: viewController)
// ...
private func openGallery<T:UIViewController>(viewController: T) {
imagePicker.sourceType = .photoLibrary
imagePicker.delegate = self
viewController.present(imagePicker, animated: true)
}