0

I would like to have a Dictionary of Dictionaries. I'm coming from mostly a Python background, where I can simply allocate and assign a top-level key to be a new dictionary, then use a reference to that dictionary to update it no matter how deeply it is nested.

I am trying to do the same thing in Swift. I am using [NSObject: AnyObject] because it must be bridgeable to NSDictionary so I can store it in NSUserDefaults.

Here is an example Playground:

import Cocoa

var foo = [NSObject: AnyObject]()
foo["aa_key"] = "aa_value"
println(foo)

foo["bb_key"] = [NSObject: AnyObject]()
println(foo)

if var bar = foo["bb_key"] as? [NSObject: AnyObject] {
    bar["cc_key"] = "cc_value"
    println("bar: \(bar)")
} else {
    println("Could not get bb dictionary")
}
// bb_key is still an _empty_ dictionary in foo!
println("foo: \(foo)")

The resulting output in the console (not the playground) is:

[aa_key: aa_value]
[aa_key: aa_value, bb_key: { }]
bar: [cc_key: cc_value]
foo: [aa_key: aa_value, bb_key: { }]

I can see that in the section where the Optional result of the downcast is unwrapped into bar, that assignments to the bar Dictionary are correct. However, when I later print foo, the changes have not made it.

It appears that bar is not a proper reference to the dictionary that is stored in foo["bb_key"]. Why not?

drootang
  • 2,351
  • 1
  • 20
  • 30

1 Answers1

2

In Swift all collection types are value types unlike reference types in Objective-C, that means the object in bar is not the same object as in foo["bb_key"]

You have to reassign / update the value in foo["bb_key"]

var foo = [NSObject: AnyObject]()
foo["aa_key"] = "aa_value"
println(foo)

foo["bb_key"] = [NSObject: AnyObject]()
println(foo)

if var bar = foo["bb_key"] as? [NSObject: AnyObject] {
  bar["cc_key"] = "cc_value"
  foo.updateValue(bar, forKey: "bb_key")
  println("bar: \(bar)")
} else {
  println("Could not get bb dictionary")
}
// bb_key is still an _empty_ dictionary in foo!
println("foo: \(foo)")
vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thank you. I missed this nuance in the discussion of value types vs references. This is definitely a departure from every language I've used in the last 10 years. – drootang Sep 16 '15 at 14:32