Swift 继承场景下父类如何向子类传递事件
实现方案
继承场景下父类向子类传递事件,优先使用模板方法模式实现,无需引入闭包、通知、代理等额外机制,完全贴合Swift面向对象的继承设计逻辑,具体实现如下:
- 在父类中定义可被子类重写的事件钩子方法,把通用逻辑(比如dismiss相机)放在父类默认实现中
- 父类收到系统的
UIImagePickerController代理回调时,直接调用预先定义的钩子方法 - 子类按需重写钩子方法,在重写逻辑中先调用
super实现复用父类通用能力,再编写自身业务逻辑
代码实现
父类BaseViewController修改
class BaseViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate { func openCamera() { let picker = UIImagePickerController() picker.delegate = self picker.sourceType = .camera present(picker, animated: true) } /// 媒体选择完成钩子方法,子类可重写实现自定义业务 func didFinishPickingMedia(_ picker: UIImagePickerController, info: [UIImagePickerController.InfoKey : Any]) { // 父类默认通用逻辑:关闭相机 picker.dismiss(animated: true) } /// 相机取消钩子方法,子类可重写 func didCancelPickingMedia(_ picker: UIImagePickerController) { picker.dismiss(animated: true) } // MARK: UIImagePickerControllerDelegate func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){ // 收到系统回调后,调用钩子方法,事件自动传递给重写该方法的子类 didFinishPickingMedia(picker, info: info) } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { didCancelPickingMedia(picker) } }
子类ViewController实现
class ViewController: BaseViewController { @IBAction func cameraButtonClicked(_ sender: Any) { self.openCamera() } // 重写父类钩子方法,接收媒体选择完成事件 override func didFinishPickingMedia(_ picker: UIImagePickerController, info: [UIImagePickerController.InfoKey : Any]) { // 先调用父类实现,复用关闭相机的通用逻辑 super.didFinishPickingMedia(picker, info: info) // 编写子类自定义业务逻辑,比如获取选中图片 guard let originalImage = info[.originalImage] as? UIImage else { return } // 后续处理图片:展示、上传等 print("子类已获取选中图片,尺寸为\(originalImage.size)") } }
可选优化
如果需要强制所有继承自BaseViewController的子类必须实现媒体选择后的处理逻辑,可以将钩子方法的默认实现替换为:
func didFinishPickingMedia(_ picker: UIImagePickerController, info: [UIImagePickerController.InfoKey : Any]) { fatalError("子类必须重写`didFinishPickingMedia(_:info:)`方法实现自定义业务逻辑") }
注意:该方式会在子类未重写方法时触发运行时崩溃,适合要求所有子类必须实现对应逻辑的场景,如果部分子类不需要处理相机回调,保留空的默认实现即可。
内容的提问来源于stack exchange,提问作者Vishal Desai
相关产品推荐
相关产品推荐

