我在 may app 中遇到了一个我认为是奇怪的错误。这个问题的底部是完整的代码,它重现了我在我的应用程序中看到的内容,但这里是一个快速演示。
我创建了同一个类的两个实例,一个被声明为符合协议(protocol)的可选,另一个被声明为具体类的可选
对于这两者,我都可以通过选项链来设置计算属性,即:
anOptionalInstance?.someComputedProperty = ....
对于具体版本,我可以通过展开可选的来设置属性
if let anInstance = anOptionalInstance {
anInstance.someComputedProperty = ....
}
对于多态版本,我收到一条错误消息,提示我无法在实例上设置属性。
下面是一个完整的文件,它重现了我所看到的问题。
谁能解释一下这里发生了什么?
struct MyStruct {
var someMember: String
}
protocol MyProtocol {
var myVar: MyStruct { get set }
}
class MyType: MyProtocol {
var myVar: MyStruct {
get {
return MyStruct(someMember: "some string")
}
set {
println(newValue)
}
}
}
class UsingClass {
var anInstanceOfMyType: MyProtocol?
var anOtherInstanceOfMyType: MyType?
func someMethod() {
anInstanceOfMyType = MyType()
anInstanceOfMyType?.myVar = MyStruct(someMember: "blah")
if let anInstanceOfMyType = anInstanceOfMyType {
// The following line produces this error :Cannot assign to 'myVar' in 'anInstanceOfMyType'
anInstanceOfMyType.myVar = MyStruct(someMember: "blah blah")
}
anOtherInstanceOfMyType = MyType()
anOtherInstanceOfMyType?.myVar = MyStruct(someMember: "blah")
if let anOtherInstanceOfMyType = anOtherInstanceOfMyType {
anOtherInstanceOfMyType.myVar = MyStruct(someMember: "blah blah")
}
}
}
最佳答案
问题确实发生了,因为您试图更改类型为 MyProtocol
的常量 anInstanceOfMyType
的属性。
1。为什么 anInstanceOfMyType
是常量?
在UsingClass
的第一行,anInstanceOfMyType
实际上被声明为var
。但是,使用 Conditional Unwrapping
会创建名称为 anInstanceOfMyType
的常量,而您正试图更改该常量的属性
2。好的,但是 anInstanceOfMyType
引用了一个类的实例,所以我应该能够更改它的属性,即使它是一个常量
因为 anInstanceOfMyType
有 MyProtocol
作为类型,它可以包含一个 struct
或一个引用 一个类的实例
。
因此编译器确实应用了更安全的方法并避免您更改其属性。
解决方案
通过将 class 关键字添加到协议(protocol)的继承列表中,将协议(protocol)采用限制为类类型(而不是结构或枚举)。 class 关键字必须始终出现在协议(protocol)的继承列表中的第一个位置,在任何继承的协议(protocol)之前:
protocol MyProtocol: class {
var myVar: MyStruct { get set }
}
或
如果 MyProtocol
更新为扩展 AnyObject
protocol MyProtocol : AnyObject {
var myVar: MyStruct { get set }
}
然后很明显 anInstanceOfMyType
必须引用一个类的实例,在这种情况下您的代码可以编译。
关于swift - 在 swift 中,为什么我可以通过可选链接设置多态变量的计算属性,而不是在展开的可选上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32300734/