2016-06-10 91 views
0

我想通過字典是其中一個參數的方法填充字典。當我向鍵添加一個值時,比如15,當我嘗試第二次使用同一個鍵即15來訪問它時,它總是返回0計數。這是代碼。Swift:作爲參數傳遞的字典總是空的

private static var showWidgetMap = Dictionary<Int, [BaseWidget]>() private static var hideWidgetMap = Dictionary<Int, [BaseWidget]>()

static func initHandler() 
{ 
    let cloudWidget = CloudWidget() 
    cloudWidget.setType(CreatorConstants.CLOUD) 
    let property1 = [CreatorConstants.IMG_SRC: "cloud1", CreatorConstants.X_COORD: "100", CreatorConstants.Y_COORD: "450"] 
    cloudWidget.setPropery(property1) 

    addWidgetInLocalTimeList(15, widget: cloudWidget, delete: false) 

    let emojiWidget = CloudWidget() 
    emojiWidget.setType(CreatorConstants.EMOTICON) 
    let property2 = [CreatorConstants.IMG_SRC: "1", CreatorConstants.X_COORD: "100", CreatorConstants.Y_COORD: "550"] 
    emojiWidget.setPropery(property2) 

    addWidgetInLocalTimeList(15, widget: emojiWidget, delete: false)} 

static func addWidgetInLocalTimeList(time_milisec: Int, widget: BaseWidget, delete: Bool) { if(delete) { checkAndAdd(hideWidgetMap, key: time_milisec, widget: widget); } else { checkAndAdd(showWidgetMap, key: time_milisec, widget: widget); } }

private static func checkAndAdd(var map: Dictionary<Int, [BaseWidget]>, key: Int, widget: BaseWidget) 
{ 
    print("map count is") 
    print(map.count) 

    if var val = map[key] 
    { 
     val.append(widget); 
    } 
    else 
    { 
     var temp: [BaseWidget] = []; 
     temp.append(widget); 
     map[key] = temp 
     print(map.count) 
    } 
} 

print(map.count)總是返回0

回答

1

您需要了解值類型引用類型之間的差異。

值類型變量只是值。例如,一個數組是一個值類型。這只是「一堆東西」的價值。另一方面,引用類型是對值的引用。例如,當您創建UIViewController時,該變量實際上存儲對實際的UIviewController *的引用。

不是很明白嗎?那就是比喻時間!你創建的變量和常量是兒童。你放入變量和常量的東西是氣球。

有兩種類型的孩子,一種類型(值類型)喜歡直接在他們手中持有氣球。其他類型(引用類型)喜歡使用字符串**保持氣球。

當你傳遞一個孩子的方法,這取決於什麼類型的孩子,他的,不同的事情會發生:

  • 值類型的孩子認爲在他手中的氣球,如此緊密,該方法參數不能把它從他身上帶走。那麼它能做什麼?它創建了一個副本它!然後,它將複製到方法實現,讓它做它的事情。

  • 但是,引用類型使用字符串保存氣球。方法參數將的另一個字符串與氣球聯繫起來,以便實現可以使用字符串訪問它。因此,不會創建氣球的副本。

那麼你在這裏做錯了什麼?

由於swift字典是值類型,當您將字典傳遞給方法時,如上所述,它會創建一個副本!在實現中,您實際上是在編輯字典的副本,而不是原來的副本。這就是爲什麼原始字典仍然有一個計數爲0.

你能做什麼?

而不是用var標記參數,這是一個非常糟糕的練習順便說一句,你用inout標記它!

private static func checkAndAdd(inout map: Dictionary<Int, [BaseWidget]>, key: Int, widget: BaseWidget) 

inout修改基本上說

嘿參數,下一次你看到一個值類型,只是得到一個字符串,並將其綁到孩子拿着氣球。

還有一件事你應該做。那就是你應該改變你調用你方法的方式。

而不是

checkAndAdd(showWidgetMap, key: time_milisec, widget: widget) 

你寫

checkAndAdd(&showWidgetMap, key: time_milisec, widget: widget) 

而且奇妙的是,它的作品!

結論: 參數是啞的。他們甚至不夠聰明,無法知道何時綁定一個字符串。 使用值類型時要小心。


腳註*假設它不是nil

**不是String類型,但實際的字符串。

相關問題