1

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.

3
  • 1
    [String:Any] this is not an array but dictionary Commented Jul 27, 2016 at 14:06
  • 4
    "the referenced array ..." – your problem starts here. Arrays are value types. Commented Jul 27, 2016 at 14:08
  • Yep sorry Ozgur. i edited that. Commented Jul 27, 2016 at 14:18

1 Answer 1

3

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)
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Perfect thank you. So i need to use NSMutableArray to be able to use references ? If i want to pass data between UIViewControllers and that i want to change data from one controller that will update the other. How can i do that ? Thank you man.
@user2434385 I found issue in answer, please check correction. If you have complex data with nested mutated arrays/dictionaries, then I suggest you to write custom class for this needs.
thank u man, do u know any tutorial or example for this kind of custom class ?
i do not understand why even with force unwrapping the compiler tells me it's a immutable array ...
@user2434385 check my suggest (update 2) for passing data between view controllers, maybe it will help you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.