如何在Swift 2.0中创建NSMutableDictionary

12

最近我把Xcode更新到7,它包含了Swift 2.0编译器。在此之前,我用旧版本的Swift创建了项目。在那个版本中,我像下面这样创建了NSMutableDictionary


    let dictParams:NSMutableDictionary? = ["test" : "test", 
        "username" : txtEmail.text, 
        "password" : txtPassword.text, 
        "version" : "1.0", 
        "appId" : "1", 
        "deviceId" : "fasdfasdfrqwe2345sdgdfe56gsdfgsdfg"
    ];

在上述代码中,txtEmail.texttxtPassword.text是我的文本字段,并在运行时填充值。

这段代码在旧版本的Swift中可以正常工作,但升级到Swift 2.0后,会出现以下错误:

Cannot convert value of type '[String : String?]' to specified type 'NSMutableDictionary?'

有什么问题请指教。


1
提示:在 [String : String?] 中的问号是相关的。 txtEmail.text 是什么类型? - Martin R
你确定需要一个NSMutableDictionary吗?为什么不使用本地的Swift字典呢? - Stephen Darlington
1
txEmail.text或txtPassword.text,它们是可选值吗?如果是,您是否介意将它们解包并检查错误是否仍然存在。 - iamyogish
@iamyogish 那就是问题所在。感谢您的更新。 - Bhavin_m
3个回答

22

仅通过在Xcode 7中打开NSMutableDictionaryNSDictionary类接口,您就可以轻松地看到底层类型实际上是[NSObject: AnyObject]。这意味着该值不能为nil

txtEmail.text!txtPassword.text!这样解除包装的文本值可能看起来不错,并帮助您摆脱编译错误,但这是一个糟糕的选择,因为技术上UITextFieldtext属性是可选的,如果出现这种情况,您的应用程序可能会崩溃!

为了确保安全,请执行以下操作:

let dictParams: NSMutableDictionary? = ["test" : "test", 
    "username" : txtEmail.text ?? "", // Always use optional values carefully!
    "password" : txtPassword.text ?? "",
    "version" : "1.0", 
    "appId" : "1", 
    "deviceId" : "fasdfasdfrqwe2345sdgdfe56gsdfgsdfg"
]

顺便提一下,如果使用NSMutableDictionary并非必要,请考虑使用Swift字典,如下所示:

如果不是必须使用NSMutableDictionary的话,建议您考虑使用Swift字典,代码示例如下:

var mutableDictionary = [String: AnyObject] 

// OR this if the value can be nil
var mutableDictionary = [String: AnyObject?] 

点赞使用空值合并运算符 ?? 代替强制解包 ! - redent84

1

将文本框中的内容更改为"username" : txtEmail.text! 而不是 "username" : txtEmail.text

因此,最终代码如下所示

let dictParams:NSMutableDictionary? = ["test" : "test", 
        "username" : txtEmail.text!,     //Add ! here 
        "password" : txtPassword.text!,  //Add ! here
        "version" : "1.0", 
        "appId" : "1", 
        "deviceId" : "fasdfasdfrqwe2345sdgdfe56gsdfgsdfg"
    ];

3
你只是把一个编译错误变成了运行时错误,太棒了! - redent84
1
不行,因为textField.text从来不会是nil!如果你将textField的文本赋值为nil,并立即打印出来,它将打印空字符串,而不是nil。这是因为内部的.text将nil值转换为空字符串。 - Borzh

0

txtEmail.text和/或txtPassword.text返回一个可选项,这就是为什么它告诉你要更改类型的原因。你可以将字典重写为Swift字典(这是我推荐的方法)。当你这样做时,你可以将对象设置为可选的,或者将其保留为String,并在创建字典时强制解包可选字符串。

var optionalString: String?

var someDict: [String: String?] = ["test": "test", "test1": optionalString]

是的,那也是实现这个的另一种方式,但我在现有代码中进行了小改动,它可以工作。顺便说一句,谢谢更新 :) - Bhavin_m

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接