Reputation: 587
I've been trying to debug something in my code and came across this. You can put this directly in playground
.
import UIKit
class testObj {
var prop1: Int?
}
var testObjInst = testObj()
var myDic : [String : testObj] = [:]
testObjInst.prop1 = 1
myDic["A"] = testObjInst
testObjInst.prop1 = 2
myDic["B"] = testObjInst
testObjInst.prop1 = 3
myDic["C"] = testObjInst
print(myDic["A"]?.prop1) //prints 3
if let myVal = myDic["A"] {
myVal.prop1 = 5
}
print(myDic["A"]?.prop1) //prints 5
How is the myVal
variable changing the value for myDic["A"]
? Shouldn't myVal
be assigned to the result of calling myDic["A"]
and the return of this call would ultimately be a new instance of the object?
Edit 1: My segues are performed like this:
if segue.identifier == segueIDs.air {
if let vc = segue.destination as? PointsTableViewController {
//these are the dictionaries.
vc.rewardProgramsDic = rewardProgramsDic
}
}
The issue I've been getting is when a property was set in the destination
viewController
, when I would press back
and print the values in the rewardProgramsDic
the values would have changed. I tried setting breakpoints
on the rewardProgramsDic
as well as using didSet
to try and catch the change but neither of those is called when a property is updated in the destination
viewController
.
Edit 2:
In the originating viewController
:
var rewardProgramsDic: [String: IndividualRewardProgram] = [:]
In the destination tableViewController
var rewardProgramsDic: [String: IndividualRewardProgram] = [:]
Upvotes: 2
Views: 89
Reputation: 587
Using this function:
func address<T: AnyObject>(o: T) -> Int {
return unsafeBitCast(o, to: Int.self)
}
and calling it the parent view controller
, like this:
print(NSString(format: "%p", address(o: rewardProgramsDic["ID1"]!)))
and then calling this same function in the destination view controller
, I confirmed that the parent view controller
and the destination view controller's
variables were pointing to the same place in memory. This explains why I was getting the cascading down change explained with my conversation with @Nirav.
Thank you both for your responses.
Upvotes: 0
Reputation: 2124
Here, you are getting such result because you are using Class.
Class is reference types & reference types are not copied when they are assigned to a variable or constant, or when they are passed to a function.
Mean by updating object value, will updates all the instances where they actual assigned. Here in above example,
testObjInst.prop1 = 1
myDic["A"] = testObjInst // myDic["A"]?.prop1 :- 1
testObjInst.prop1 = 2
myDic["B"] = testObjInst // myDic["B"]?.prop1 :- 2 & myDic["A"]?.prop1 :- 2
testObjInst.prop1 = 3
myDic["C"] = testObjInst // myDic["C"]?.prop1 :- 3 & myDic["B"]?.prop1 :- 3 & myDic["A"]?.prop1 :- 3
if let myVal = myDic["A"] { //So Here, myDic["A"]?.prop1 :- 3
//Here, myDic["A"] class instance is assigned to myVal object,
//So changing value in myVal object directly reflect in all object.
myVal.prop1 = 5 // myDic["A"]?.prop1 :- 5 & myDic["B"]?.prop1 :- 5 & myDic["C"]?.prop1 :- 5
}
Upvotes: 1