【问题标题】:How to create NSMutableDictionary in swift 2.0如何在 swift 2.0 中创建 NSMutableDictionary
【发布时间】:2015-09-24 12:58:44
【问题描述】:

最近我将 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?'

有什么问题请指教。

【问题讨论】:

  • 提示: [String : String?] 中的问号是相关的。 txtEmail.text 是什么类型的?
  • 你确定你需要一个 NSMutableDictionary 吗?为什么不使用原生 Swift 字典?
  • txEmail.text 或 txtPassword.text,它们是可选值吗?如果是这样,您是否介意打开它们并检查错误是否仍然存在。
  • @iamyogish 这就是问题所在。感谢更新。

标签: swift swift2


【解决方案1】:

只需从 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 字典:

var mutableDictionary = [String: AnyObject] 

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

【讨论】:

  • 为空合并运算符 ?? 点赞,而不是用 ! 解包
【解决方案2】:

简单的改变 "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"
    ];

【讨论】:

  • 你刚刚将编译错误转换为运行时错误,耶!
  • 不,因为 textField.text 永远不会为零!如果将 textField 的文本分配给 nil,并立即将其打印出来,它将打印空字符串,而不是 nil。这是因为 .text 在内部将 nil 值转换为空字符串。
【解决方案3】:

txtEmail.text 和/或txtPassword.text 正在返回一个可选项,这就是它告诉您更改类型的原因。您可以将 dict 重写为 swift 字典(这是我推荐的)。当您这样做时,您可以使对象成为可选对象,或者将其保留为 String,并在创建 dict 时删除可选字符串。

var optionalString: String?

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

【讨论】:

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