Swift:作为参数传递的字典始终为空

时间:2016-06-10 08:37:57

标签: ios swift

我想通过一种方法填充Dictionary,其中字典是参数之一。当我向key添加一个值时,比如15,当我尝试用同一个键第二次访问它时,它总是返回0计数。这就是代码。

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 个答案:

答案 0 :(得分:1)

您需要了解值类型引用类型之间的区别。

值类型变量只是值。例如,数组是值类型。它只是&#34;一堆东西的价值&#34; *。另一方面,引用类型是对值的引用。例如,当您创建UIViewController时,该变量实际上存储了对实际UIviewController *的引用。

不是很明白吗?然后是它的比喻时间!您创建的变量和常量是子项。你在变量和常量中放置的东西都是气球。

有两种类型的儿童,一种类型(价值类型)喜欢直接在他们手中持有气球。另一种类型(引用类型)喜欢使用字符串**来保存气球。

当您将孩子传递给某个方法时,根据他的孩子类型,会发生不同的事情:

  • 一个值类型的孩子手里拿着气球,所以方法参数不能将气球从他手中拿走。那它能做什么呢?它会创建一个副本!然后它将副本带到方法实现中让它做它的事情。

  • 但是,引用类型使用字符串保存气球。方法参数将另一个字符串绑定到气球,以便实现可以使用字符串访问它。因此,不会创建气球的副本。

那你在这里做错了什么?

由于swift词典是值类型,当您将字典传递给方法时,如上所述,它会创建副本!在实现中,您实际上是在编辑字典的副本,而不是原始字典的副本。这就是为什么原始字典的计数仍为0。

你能做什么?

不是用var标记参数,这是一个非常糟糕的做法btw,你用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类型,而是实际字符串。