2015-11-16 154 views
0

我創建了一個城市類,它由幾個City對象組成,每個City對象都有特定的數據。由於數據是固定的,我想將它分配給Cities對象的init()函數。用對象填充數組

// CASE 1 - ERROR 

class Cities : NSObject { 
    var cityList:[City] 
    override init() { 
     cityList = [] 
     let city = City() 

     city.fill("LA" , "USA") 
     self.cityList.append(city) 
     city.fill("Amsterdam" ,"Netherlands") 
     self.cityList.append(city) 
     city.fill("Beijing" , "China") 
     self.cityList.append(city) 

結果:北京北京


// CASE 2 - CORRECT 

class Cities : NSObject { 
    var cityList:[City] 
    override init() { 
     cityList = [] 
     var city:City 

     city = City(name: "LA" ,country: "USA") 
     self.cityList.append(city) 
     city = City(name: "Amsterdam", country: "Netherlands") 
     self.cityList.append(city) 
     city = City(name: "Beijing" , country: "China") 
     self.cityList.append(city) 

結果:LA,阿姆斯特丹,北京

當我運行這個第一個腳本,我得到一個很好的城市對象陣列中有3個城市,都是北京。

在正確的情況下,數據由對象City的init函數分配。現在一切都按預期工作。

在這兩種情況下,我只創建了一個城市對象:城市。爲什麼這種Swift行爲有所不同? 使用Apple Swift 2.1版

+0

考慮如果你可以使用一個結構來代替這個類,你可以使用值語義而不是引用嗎? – Wain

回答

1

在案例1中,您只創建了一個City對象,這是創建對象的行:

let city = City() 

城市是一個類,它是一個參考類型。這意味着它會將您指向內存中的相同位置。你第一次調用:

city.fill("LA" , "USA") 

設置屬性爲「LA」和「美國」,第二個電話

city.fill("Amsterdam" ,"Netherlands") 

到內存中的同一個地方,並用新值替換的屬性和第三次呼叫也是最後一次呼叫,所以最終會出現這些值。 你的陣列cityList有三個項目,它指向同一個地方的記憶,這是爲什麼你看到相同的對象:

cityList[0] === cityList[1] === cityList[2] 

在每次創建調用構造新的對象,例如時間案例2:

City(name: "LA" ,country: "USA") 

構造分配與完全新的對象結束了新的內存地址,所以每次打電話:

City(name:...) 

你的city對象指向內存中的不同位置。

+0

這聽起來很合邏輯。對於正確的情況。所以通過調用構造函數,我總是創建一個新的對象。這是否也意味着當我創建阿姆斯特丹時城市對象(LA)被刪除。或者它保留在內存中但不能使用? – Vincent

+0

是的,當你調用構造函數時,你創建了一個新的對象,在你的例子中,城市將存儲新的引用,它指向你的新對象,舊的引用將被覆蓋。在你的例子中,將它添加到數組中,以便引用計數遞增,並且仍然可以通過調用cityList [0]來訪問它。如果你不想將它添加到數組中,對象將被釋放。 – Greg

+0

很好的解釋。謝謝 – Vincent

1

在第一種情況下,您創建單個City對象,然後用不同的數據填充它,但它是一個對象,您創建它一次,只需將三個指針放在數組中,叫fill你改變這種單一的對象中,並在您init你有3個指針到包含最後一個數據

在第二種情況下一個對象數組的末尾數據創建3個不同的對象,並把它添加到陣列