Swift中为何无法为get-only的localVc对象的可写属性赋值?
问题原因分析
你遇到的编译报错核心是Swift编译器对协议类型实例的属性修改规则限制,具体逻辑如下:
- 对于类(引用类型)的实例来说,即使持有实例的变量是只读的,也可以自由修改实例的可变属性——因为只读限制的只是变量存储的引用地址,不是引用指向的对象本身
- 但对于结构体/枚举(值类型)的实例来说,修改属性本质是对整个值实例重新赋值,这就要求持有实例的变量必须是可读写的
你的HVSHomeVideoChildProtocol没有限制只能由类实现,编译器无法确认遵守该协议的类型是引用类型还是值类型,会按照最保守的规则处理:认为修改该协议类型实例的属性,等同于修改实例本身。而你的localVc是只读计算属性,不允许被修改,因此触发编译错误。
解决方案
有两种常用的修复方式:
方案1:给协议添加类实现限制
在协议定义时加上AnyObject约束,明确告诉编译器该协议只能由类实现,修改属性不需要修改实例引用本身:
// 修改协议定义,添加AnyObject限制 public protocol HVSHomeVideoChildProtocol: AnyObject { var refreshGesture: UIPanGestureRecognizer! {get set} }
修改后原有代码localVc.refreshGesture = refreshGesture可以正常运行。
方案2:转成具体类类型再修改属性
如果不想修改协议定义,可以将协议类型的实例转成具体的实现类类型,编译器识别到是引用类型后就会允许修改属性:
// 直接用你持有的具体类实例赋值即可 singleLocalVc.refreshGesture = refreshGesture
内容的提问来源于stack exchange,提问作者zox01
相关产品推荐
相关产品推荐

