Showing posts with label Swift iOS mobile iPhone Xcode Apple computer languages strict class reference value type. Show all posts
Showing posts with label Swift iOS mobile iPhone Xcode Apple computer languages strict class reference value type. Show all posts

Wednesday, November 4, 2015

Swift 2.0, Reference and Value Types, and Unintended Sharing.

I have recently begun learning swift 2.0, because I would like to build an iOS app and I really don't want to have to learn Objective-C.  I am trying to learn it the right way, which means understanding how the language works and not just mutating examples to learn by accident.

I have been reading a lot about structs and classes, and the difference between value types and reference types.  In short, classes pass around object references and structs make copies whenever you pass them around.  I visualize it in old-school terms:  Classes use pointers, but with structs the variable IS the data.

This seems pretty simple - especially if you are comfortable with object languages.  I have watched a few Apple videos, though, and they make it sound revolutionary.  This one in particular goes on about unintended sharing - I pass a handle to the same object into two different contexts where they are expected to be independent.  Change one, impact the other, etc.  His illustrative example was "I created a thermostat object, assigned it to my house.  Then I set the thermostat in my oven to 450, and my house caught on fire!"  Paraphrase.  Gag - what a juvenile way to introduce a language feature.  They could have at least used a real-world scenario they came across implementing their standard libraries that made this feature such a deal-maker.

This seems to me to be very valuable to a college student, or someone learning an object language coming from C, but really, is this that big of a deal?  I can honestly say that I haven't had a bug of this type in my code, that I have detected of course - for decades.  On the other hand, I just spent an agonizing couple of days trying to figure out why extremely routine code did not work.  Take this example:

var map = [String: [String: String]]();
var subMap = [String: String]();
map["map"] = subMap;

subMap["1"] = "2";

For those who don't know swift, this means create a map which can hold maps of string value/pairs.  Next, create a string value/pair map, and assign it to the key "map" in the top-level map.  Finally, assign the key/value entry "1" -> "2" into the sub map.  The expectation being that it will be reflected in the top-level map as well.  This is pretty standard in Java - I do it a lot so I can factor code which handles the sub trees into external code.  In this case, it doesn't work.  Because collections in swift are structs - I.E., value types - the assignment on the third line makes a copy which is unaffected by the assignment on line 4.  I came up with this working code after much hair-pulling:

var map: Dictionary = [String: [String: String]]();
map["map"]!["1"] = "2";

And only later uncovered the reason that I explained before.  I find this extremely annoying, but certainly manageable once you understand the language - and maybe even something you can use effectively.  But I found his example so contrived that I basically checked out.