我不明白为什么我在这个方法上出错:
let loginCountKey = "loginCount"
let appReviewParamsKey = "appReviewParams"
func resetLoginCount() {
let defaults = NSUserDefaults.standardUserDefaults()
if let reviewParameters = defaults.valueForKey(appReviewParamsKey) as? NSMutableDictionary {
reviewParameters[loginCountKey] = 1
defaults.setObject(reviewParameters, forKey: appReviewParamsKey)
defaults.synchronize()
}
}
setObject行给出了一个错误:caught "NSInternalInconsistencyException", ... mutating method sent to immutable object"
调试时,reviewParameters显示为NSMutableDictionary。我也试过if var而不是if let(因为它应该是不必要的)并且得到了同样的错误。
我也尝试将值设置为NSNumber(int:1)而不是1。
为什么会导致给定错误?
答案 0 :(得分:1)
有两个问题:
NSUserDefaults
在转换为基础类型在Swift中,推荐的方法是使用本机Swift类型和变量(var),例如
func resetLoginCount() {
let defaults = NSUserDefaults.standardUserDefaults()
if var reviewParameters = defaults.objectForKey(appReviewParamsKey) as? [String:AnyObject] {
reviewParameters[loginCountKey] = 1
defaults.setObject(reviewParameters, forKey: appReviewParamsKey)
defaults.synchronize()
}
}
答案 1 :(得分:1)
NSUserDefaults.objectForKey
(一般KVC方法valueForKey
必须调用的地方)在找到该默认密钥的字典格式数据时返回不可变NSDictionary
。
使用as?
是强制转换,而不是转换。也就是说,你告诉Swift解释你拥有的词典好像它是 NSMutableDictionary
(即使它没有,这就是失败的原因)。如果您想转换 NSDictionary
到NSMutableDictionary
,您需要从前者创建后者的实例(使用mutableCopy
或initWithDictionary:
)。
但是你甚至不需要在这里使用Foundation词典 - NSDictionary
会自动桥接到Swift词典,你可以强制转换为as
正确的键/值类型。您可以使用if var
代替if let
将可选项绑定为可变值:
if var reviewParameters = defaults.objectForKey(appReviewParamsKey) as? [String: Int] {
reviewParameters[loginCountKey] = 1
defaults.setObject(reviewParameters, forKey: appReviewParamsKey)
defaults.synchronize()
}