在 NSUserDefaults 中存储字典导致 EXC_BAD_ACCESS

Storing Dictionary in NSUserDefaults causing EXC_BAD_ACCESS

//Declarations
var scoreIncrement:Int = 0
var team = ""
var userScore = Dictionary<String,Int>()

//Set Values
team = "USA"
userScore[team] = 0

//Store in NSUserDefaults
NSUserDefaults.standardUserDefaults().setObject(userScore, forKey: "userScore")
NSUserDefaults.standardUserDefaults().synchronize()

//Increment Score
scoreIncrement = 1
userScore[team]! += scoreIncrement

以上代码在代码的最后一行给出 'EXC_BAD_ACCESS(code=EXC_I386_GPFLT)' 错误。但是,如果我注释掉一行:

NSUserDefaults.standardUserDefaults().setObject(userScore, forKey: "userScore")

错误消失了。知道为什么会这样,我什至还没有从 NSUserDefaults 中检索字典。

通过在保存字典后立即从 NSUserDefaults 中检索字典来解决问题:

var userScoreTemp : AnyObject? = NSUserDefaults.standardUserDefaults().objectForKey("userScore")
    if userScoreTemp != nil {
        userScore = userScoreTemp! as Dictionary
    }

我也遇到了这个问题。原来是KVO问题。有可能您已经释放了一个 观察到 这个值的对象,因此消息被发送但没有像预期的那样被接收。

我的解决方案是从关联的已释放对象中删除观察者。永远记住,如果您 addObserver:forKeyPath:options:context: 将其与关联的 removeObserver:forKeyPath: 调用相匹配。

我遇到了同样的问题。

我将字符串值存储在 NSUserDefaults 中,例如:

[[NSUserDefaults standardUserDefaults] stValue:@"Rahul" forKey:@"Name"];

一段时间后,它在同一点崩溃,写入相同的值。原因是在此期间之后,我使用如下代码注册了 NSUserdefaults 中的更改:

[[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(valueChange) name:NSUserDefaultsDidChangeNotification object:nil];

这是在初始化时在导入器中完成的。在导入器被释放后,对用户默认值的新写入触发了观察者寻找一个已经消失的对象。崩溃。

解决方案当然是移除观察者。

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [默认 removeObserver:self forKeyPath:@"Name"];