如何在Swift子类重写父类只读属性为读写并赋值给父类
如何在Swift子类中将父类的只读属性重写为可读写属性
报错核心原因
父类声明的只读计算属性没有配套存储后端,重写时直接在setter中给super对应属性赋值属于非法操作——父类本身没有为该属性实现setter,自然无法接收写入操作,这就是编译器抛出Cannot assign to property: 'inputAccessoryViewController' is a get-only property错误的根本原因。
Swift官方文档提到的「子类可将继承的只读属性重写为可读写属性」,要求是子类自行提供属性的完整读写实现,而非给父类的只读属性强行追加setter。
inputAccessoryViewController场景的正确实现
不需要向父类属性传值,仅需在子类中新增私有存储属性承接写入的值,重写属性的getter、setter对接该存储属性即可:
class InputAccessoryEnabledTextView : UITextView { private var _customInputAccessoryVC: UIInputViewController? override var inputAccessoryViewController: UIInputViewController? { get { _customInputAccessoryVC } set { _customInputAccessoryVC = newValue } } }
逻辑说明
- UIKit对该属性的调用逻辑为:当响应者成为第一响应者、系统即将展示输入视图时,仅会主动读取该属性的getter返回值,将返回控制器对应的视图挂载到输入视图上方。系统本身不会主动向该属性写入值,因此父类仅声明get-only接口约束子类返回值即可。
- 错误实现的问题完全出在setter中尝试写入
super.inputAccessoryViewController = newValue这一行:父类的只读属性不存在写入入口,该操作本身就不符合语法规则。 - 重写后的属性对外完全表现为可读写属性:你可以在业务代码中直接给该属性赋值自定义的输入辅助控制器实例,系统弹出键盘时会自动读取你设置的值加载对应辅助视图,完全符合UIResponder文档的使用要求。
内容的提问来源于stack exchange,提问作者clearlight
相关产品推荐
相关产品推荐

