2017-01-12 2 views
2

Я пытался отладить что-то в своем коде и наткнулся на это. Вы можете поместить это прямо в 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 

Как переменная myVal изменения значения для myDic["A"]? Не следует ли присвоить myVal результат вызова myDic["A"], и возврат этого вызова в конечном итоге станет новым экземпляром объекта?

Edit 1: Мои перетекает выполняются так:

if segue.identifier == segueIDs.air { 
     if let vc = segue.destination as? PointsTableViewController { 
      //these are the dictionaries. 
      vc.rewardProgramsDic = rewardProgramsDic 
     } 
    } 

вопрос я получаю, когда собственность была установлена ​​в destinationviewController, когда я нажмите back и распечатать значения в rewardProgramsDic значения изменились бы. Я попытался установить breakpoints на rewardProgramsDic, а также с помощью didSet, чтобы попытаться поймать изменение, но ни один из них не вызван, когда свойство обновляется в destinationviewController.

Edit 2:

В происходящей viewController:

var rewardProgramsDic: [String: IndividualRewardProgram] = [:] 

В пункте назначения tableViewController

var rewardProgramsDic: [String: IndividualRewardProgram] = [:] 
+3

Потому что все ключи указывают на тот же экземпляр testObj. Сравните с этим http://stackoverflow.com/q/41343905/6433023 –

+1

вам нужно скопировать экземпляр, чтобы назначить его myDic – GeneCode

+0

Спасибо вам обоим. Это определенно помогло. Один вопрос о ключах, указывающих на экземпляры 'testObj'.Если бы я должен был передать этот «словарь» в 'segue', значит, экземпляр' '' '' '' '' '' '' viewController 'этого '' словаря' 'также указывает в память на одно и то же место? Я., изменение в '' '' '' '' '' '' '' '' '' '' '' '' ''' '' '' '' изменило бы этот' словарь', если бы я должен был нажать кнопку 'назад'? – Sami

ответ

1

Здесь, вы получаете такой результат, потому что вы используете класса.

Класс ссылочные типы & ссылочные типы не копируются, когда они присвоены переменной или постоянной, или, когда они передаются в функции.

Средство путем обновления значения объекта обновляет все экземпляры, где они фактически назначены. Здесь, в приведенном выше примере,

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 
} 
0

Используя эту функцию:

func address<T: AnyObject>(o: T) -> Int { 
    return unsafeBitCast(o, to: Int.self) 
} 

и назвав его parent view controller, как это:

print(NSString(format: "%p", address(o: rewardProgramsDic["ID1"]!))) 

и затем вызвать эту же функцию в destination view controller, я подтвердил, что переменные parent view controller и destination view controller's указывали на то же место в памяти. Это объясняет, почему я получал каскадное изменение, объясненное моим разговором с @Nirav.

Благодарим вас обоих за ваши ответы.

+0

Ответ на маркировку @ Сагара как ответ, а не мой, поскольку это действительно было в центре вопроса. – Sami

Смежные вопросы