我想通过一种方法填充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.
答案 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
类型,而是实际字符串。