Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I was recently working on some test code, building silly view hierarchys and I ran across this little bit of code that made me squint a little extra hard.

var parentView: UIView = UIView()  //Warning here
parentView.addSubview(UIImageView())

On the first line is the following warning:

Variable 'parentView' was never mutated; consider changing to 'let' constant

I'm confused as to why this element is not, or why the compiler believes it is not, being mutated. I thought perhaps that Swift was detecting that a collection within the object was being mutated, and not the properties of the object itself. This lead me to attempt the following:

let strings: [String] = []
strings.append("Hi") //This is an error

Given the above code, the only explanation I can come up with is that there is a bug somewhere. Am I missing a keyword somewhere that allows this situation to make sense? Something along the line's of C++'s "mutable" keyword?

If it's not a bug, I'd like to see this scenario re-created in a class that does not inherit from UIObject, so I can understand what causes this.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
175 views
Welcome To Ask or Share your Answers For Others

1 Answer

This is not a bug. For class instances (which are reference types), as e.g. your UIView instance, you may mutate instance properties even if the instance itself is a constant (let). Arrays, on the other hand, are treated as value types in Swift, and members of a constant array (let arr ...) may not be mutated.

Hence, you never actually mutate parentView itself (parentView = UIView() would be a mutation of itself), only its members, and in such a case, it make sense (as the compiler notes) to mark parentView as a constant.

If you create an instance of a structure and assign that instance to a constant, you cannot modify the instance’s properties, even if they were declared as variable properties:

...

This behavior is due to structures being value types. When an instance of a value type is marked as a constant, so are all of its properties.

The same is not true for classes, which are reference types. If you assign an instance of a reference type to a constant, you can still change that instance’s variable properties.

From Language Guide - Properties.

...

You’ve actually been using value types extensively throughout the previous chapters. In fact, all of the basic types in Swift—integers, floating-point numbers, Booleans, strings, arrays and dictionaries—are value types, and are implemented as structures behind the scenes.

All structures and enumerations are value types in Swift. This means that any structure and enumeration instances you create—and any value types they have as properties—are always copied when they are passed around in your code.

From Language Guide - Classes and Structures.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...