2016-06-10 271 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类型,但实际的字符串。