Я использую CropViewController для быстрого и только что установил вчера, так что мой модуль обновлен. Мне это очень нравится, молодец, но я думаю, что произошла утечка памяти.
Я просто создаю новый UIViewController и представляю его модально. У меня есть UIImageView на этом контроллере, и у него есть распознаватель касаний. Я использую UIImagePickerController и представляю объект CropViewController, когда выбор мультимедиа заканчивается, например:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
let cropVC = CropViewController(croppingStyle: .circular, image: selectedImage)
cropVC.delegate = self
picker.present(cropVC, animated: false, completion: nil)
}
}
После завершения обрезки и отклонения этого UIViewController deinit
никогда не вызывается. Если я меняю метод делегата imagePickerController
следующим образом;
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
self.imageView.image = selectedImage
}
}
тогда, если меня увольняют, deinit
звонит. Я не устанавливаю никаких специальных элементов, здесь только UIViewController, UIImageView и UIImagePickerController. Я что-то неправильно настроил или это утечка памяти?
Когда я вызываю deinit
в вашем классе CropViewController.swift
, он не вызывается.
Привет @kcankaynak!
Ой-ой. Ты прав. Это определенно пахнет утечкой памяти. Мне нужно будет попробовать это в образце приложения, когда у меня будет возможность. Спасибо, что дали мне знать!
У меня такая же проблема, существует цикл сохранения, из-за которого мой UIViewController (тот, который представляет ваш VC урожая) не выпускается, он не вызывает метод deinit, как упоминалось в @kcankaynak . Я думал, что ваш делегат croppingVC не СЛАБЫЙ, потому что у вас было свойство делегата как
public var delegate: CropViewControllerDelegate? {
didSet { self.setUpDelegateHandlers() }
}
так я подумал .. может быть
публичный слабый делегат var: CropViewControllerDelegate? {
didSet {self.setUpDelegateHandlers ()}
}
исправлю ... но этого не произошло :(
хорошо .. Я исправил это следующим
1- Я сделал делегата слабым, потому что делегаты всегда должны быть слабыми
2- Я сделал самовызовы внутри обработчиков, чтобы быть [слабым я]
В вашем CropViewController.swift просмотрите обратные вызовы onDid ...
fileprivate func setUpDelegateHandlers() {
guard let delegate = self.delegate else {
onDidCropToRect = nil
onDidCropImageToRect = nil
onDidCropToCircleImage = nil
onDidFinishCancelled = nil
return
}
if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didCropImageToRect:angle:))) {
self.onDidCropImageToRect = {[weak self] rect, angle in
delegate.cropViewController!((self)!, didCropImageToRect: rect, angle: angle)
}
}
if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didCropToImage:withRect:angle:))) {
self.onDidCropToRect = {[weak self] image, rect, angle in
delegate.cropViewController!((self)!, didCropToImage: image, withRect: rect, angle: angle)
}
}
if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didCropToCircularImage:withRect:angle:))) {
self.onDidCropToCircleImage = {[weak self] image, rect, angle in
delegate.cropViewController!((self)!, didCropToCircularImage: image, withRect: rect, angle: angle)
}
}
if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didFinishCancelled:))) {
self.onDidFinishCancelled = { [weak self] finished in
delegate.cropViewController!((self)!, didFinishCancelled: finished)
}
}
}
Это было объединено в другой пиар. Спасибо за это!
Самый полезный комментарий
хорошо .. Я исправил это следующим
1- Я сделал делегата слабым, потому что делегаты всегда должны быть слабыми
2- Я сделал самовызовы внутри обработчиков, чтобы быть [слабым я]
В вашем CropViewController.swift просмотрите обратные вызовы onDid ...