In swift, why can I set a computed property of a polymorphic variable via optional chaining, but not on an unwrapped optional? -


i ran think strange error in may app. @ bottom of question complete code reproduces seeing in app, here quick demonstration.


i create 2 instances of same class, 1 declared optional conforming protocol other optional of concrete class

for both can set computed property via option chaining ie:

anoptionalinstance?.somecomputedproperty = .... 

for concrete version can set property unwrapping optional

if let aninstance = anoptionalinstance {   aninstance.somecomputedproperty = .... } 

for polymorphic version, error message says can't set property on instance.


below complete file reproduces issue seeing.

can explain happening here?

struct mystruct {   var somemember: string }  protocol myprotocol {   var myvar: mystruct { set } }  class mytype: myprotocol {   var myvar: mystruct {     {       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 {        // following line produces error :cannot assign '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")     }   } } 

the problem happen because trying change property of constant aninstanceofmytype type myprotocol.

1. why aninstanceofmytype constant?

at first line of usingclass, aninstanceofmytype declared var. conditional unwrapping constant name aninstanceofmytype created, , trying change property of constant

2. ok aninstanceofmytype references instance of class, should able change properties if it's constant

since aninstanceofmytype has myprotocol type, contain struct or reference instance of class. compiler apply safer approach , avoid change properties.

solution

limit protocol adoption class types (and not structures or enumerations) adding class keyword protocol’s inheritance list. class keyword must appear first in protocol’s inheritance list, before inherited protocols:

protocol myprotocol: class {   var myvar: mystruct { set } } 

or

if myprotocol updated extend anyobject

protocol myprotocol : anyobject {     var myvar: mystruct { set } } 

then becomes clear aninstanceofmytype must refer instance of class, in case code compile.


Comments

Popular posts from this blog

c# - Binding a comma separated list to a List<int> in asp.net web api -

Delphi 7 and decode UTF-8 base64 -

html - Is there any way to exclude a single element from the style? (Bootstrap) -