I recently came across this question on Twitter:
Hey #swiftlang peeps: How do you create an var that holds an immutable Array? As in a var that you can assign different immutable Arrays to?
— Mike R. Manzano (@bffmike) October 17, 2014
This is an interesting question. As a developer coming from Objective-C and the Cocoa frameworks, we’re used to distinguishing between NSArray and NSMutableArray. It’s generally bad practice to expose an NSMutableArray as a public property on an object.
The problem is that another part of the app could modify the contents of the pizzaMenu array without the knowledge of the Pizzeria object. The Pizzeria still points to the same object it always has; from its perspective, nothing has changed. This is bad.
Instead, a better practice is to only expose an immutable NSArray. This way, whenever any change happens, the setter method will be called. The Pizzeria is always aware of what’s happening.
Array type is built into the language. Though you can still use NSArray and NSMutableArray, it’s often not necessary; the native Array type is plenty capable.Pizzeria object and external code referenced the same object, so we had to expose an NSArray that does not have APIs for changing its contents.CGRect variables have the same value, it simply means that the two rects contain the same data. A change to one rect will never change the value of another rect stored in a separate variable.structs can have methods just like classes can. Swift’s built-in collections (Array and Dictionary) are value types.Array never affects any other variable, anywhere.pizzeria.pizzaMenu is a mutable var property, modifying the array we get back from the pizzeria has no effect on the pizzeria’s copy of the data. They are separate arrays, separate values, and we can’t change their copy unless we go through the setter.obj.someInts.append(1) causes a new value to be constructed, which is then assigned back into the someInts property!NSArray and NSMutableArray necessary in the first place. If you need a shared array, you can still use the Cocoa types. In every other case, Swift’s solution is safer, simpler, and more concise.mutating if they’re going to modify any data. Otherwise, they cannot be called on a value stored in a let variable. ↩
Leave a comment