Я создаю настраиваемую ячейку табличного представления, которая позволяет пользователю добавлять, снимать или просматривать загруженные фотографии.
Я обнаружил, что эта ячейка остается в памяти навсегда даже после закрытия табличного представления, создавая странный график памяти . Я хочу, чтобы ячейка была закрыта правильно , но мне трудно понять, что происходит.
График показывает, что на мою ячейку сильно ссылается addPhotoTapAction. context .
addPhotoTapAction: ((ItemInfoCell) -> Void)? - это переменная класса ячейки, используемая для хранения пользовательского ввода, обрабатывающего закрытие. Замыкание определяется в контроллере представления:
let infocell = tableView.dequeueReusableCell(withIdentifier: K.infocellID) as! ItemInfoCell
if item?.imageUrl == nil {
self.imageManager.actionController?.actions[2].isEnabled = false
} else {
self.imageManager.actionController?.actions[2].isEnabled = true
}
infocell.addPhotoTapAction = { [unowned self] _ in
infocell.addPhotoButton.isEnabled = false
self.imageManager.pickImage(self) { [weak self] image in
self?.imageToSave = image
infocell.itemPhoto.image = self?.imageToSave
infocell.addPhotoButton.tintColor = UIColor(ciColor: .clear)
infocell.addPhotoButton.isEnabled = true
self?.imageManager.actionController?.actions[2].isEnabled = true
}
Метод pickImage показан ниже. Он используется для представления контроллера действий с параметрами выбора изображения (сфотографировать или выбрать из библиотеки):
func pickImage(_ viewController: UIViewController, _ callback: @escaping ((UIImage) -> ())) {
picker.delegate = self
picker.mediaTypes = ["public.image"]
picker.allowsEditing = true
pickImageCallback = callback
self.viewController = viewController
actionController!.popoverPresentationController?.sourceView = viewController.view
viewController.present(actionController!, animated: true, completion: nil)
}
... и обратный вызов сохраняется для использования в вызове средства выбора didFinishPickingMediaWithInfo :
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true, completion: nil)
if let image = info[.editedImage] as? UIImage {
let squareImage = makeSquare(image)
pickImageCallback?(squareImage)
} else if let image = info[.originalImage] as? UIImage {
let squareImage = makeSquare(image)
pickImageCallback?(squareImage)
}
viewController = nil
}
Я попытался вручную установить переменную с закрытием на nil , затем переключился с [weak self] на [unowned self] на их комбинацию. Не повезло.
Я думаю, что либо pickImage (self) , либо использование свойств класса в замыкании создают сильную ссылку даже при использовании списков захвата [weak / unowned], но я все еще не уверен и не могу это исправить.
Обновление: код класса ItemInfoCell
class ItemInfoCell: UITableViewCell {
@IBOutlet weak var itemPhoto: UIImageView!
@IBOutlet weak var itemLabel: UILabel!
@IBOutlet weak var addPhotoButton: UIButton!
var addPhotoTapAction: ((ItemInfoCell) -> Void)?
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
@IBAction func takePhoto(_ sender: Any) {
if let addPhoto = self.addPhotoTapAction {
addPhoto(self)
}
}
}