user2434385
user2434385

Reputation: 301

Modify Array in swift using if var =

starting swift this past days i'm facing something that looks so simple but this makes me blow my mind.

I have an array myArray which is of type [[String:Any]].

I want simply want to modify an array by adding stuff in it :

    if var tempValue = self.myArray[0]["values"] as? [AnyObject] {
        tempValue.append("hello")
        // if i print content of self.myArray it is empty
        self.matches[0]["values"] = ["hello", "hello2"]
        // this lines does work
    }

i do not understand why when i mutate tempValue the referenced array is not mutated ? Is this a new value ?

Thanks for any explanations.

Upvotes: 1

Views: 228

Answers (1)

Yury
Yury

Reputation: 6114

1) [String:Any] is not array, it is Dictionary<String, Any>. I think you mean that myArray have type [[String:Any]]

2) Array and Dictionary types passes by value in swift, not by reference. So tempValue is different instance with same values

You can try this code:

(self.myArray[0]["values"] as? [AnyObject])?.append("hello") // - wrong!!

UPDATE:

Thought this answer marked as correct, I found issue in it. Seems like result of (self.myArray[0]["values"] as! [AnyObject]) (even with force unwrapping) will be immutable array. So you can not use append method in it. You need overwrite whole key with new array:

if var tempValue = self.myArray[0]["values"] as? [AnyObject] {
    tempValue.append("hello")
    self.myArray[0]["values"] = tempValue
}

UPDATE 2:

About passing data between view controllers. Let me show you one of my solutions for modify settings of firstViewController from secondViewController. First I define settings class:

class ControllerSettings: NSObject {
    var userInfo = Dictionary<String, AnyObject?>()
    var myArray = [AnyObject]()
    override var description: String {return "- userInfo: \(userInfo)\n - myArray: \(myArray)"}
}

firstViewController will use settings property for save it settings, and pass reference to this property to child secondViewController; after secondViewController will modify it and dismiss, firstViewController will able to check changes in viewWillAppear method

class FirstViewController: UIViewController {
    var settings = ControllerSettings()
    //...

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated) 
        print("here is actual settings:\n\(settings)")
        //...
    }
    //...

    func showSecondController() {
        let secondViewController = SecondViewController()
        secondViewController.firstViewControllerSettings = settings
        presentViewController(secondViewController, animated: true, completion: nil)
    }
}

class SecondViewController: UIViewController {
    var firstViewControllerSettings: ControllerSettings?
    //...

    func mutateSettingsAndDismiss() {
        firstViewControllerSettings?.myArray.append("NewSetting")
        dismissViewControllerAnimated(true, completion: nil)
    }
}

Upvotes: 3

Related Questions