使用 KVO 和延迟选择器观察 NSUserDefaults 时的 iOS exc_bad_access

标签 ios objective-c nsuserdefaults exc-bad-access key-value-observing

我遇到了一个奇怪的错误,并想检查我是否正确使用我的 Key 值观察对 NSUserDefaults 的更改。

我在我的应用程序中的两个地方使用了这段代码,没有问题,然后我添加了第三个 Controller 来观察“goldCount”和“energyCount”的值。现在,当我设置初始值时,应用程序因 exc_bad_access 而崩溃。我使用 performSelectorAfterDelay 在它的父 View 出现 2 秒后将此 Controller 添加到 View 中.

在显示游戏画面之前,我设置了以下属性:

//crash on this line 
[[NSUserDefaults standardUserDefaults] setInteger:200 forKey: goldCount]; 

[[NSUserDefaults standardUserDefaults] setInteger:150 forKey: energyCount];

在 3 个不同的 View Controller 中,我在 viewDidLoad 中有以下代码:
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults addObserver:self
           forKeyPath:@"goldCount"
              options:NSKeyValueObservingOptionNew
              context:NULL];

[defaults addObserver:self
           forKeyPath:@"energyCount"
              options:NSKeyValueObservingOptionNew
              context:NULL];

self.goldLabel.text = [NSString stringWithFormat:@"%i",[[GameDataManager sharedInstance] currentGoldCount]];
self.energyLabel.text = [NSString stringWithFormat:@"%i",[[GameDataManager sharedInstance] currentEnergyCount]];

以下是该类如何更新其标签:
// KVO handler
-(void)observeValueForKeyPath:(NSString *)aKeyPath ofObject:(id)anObject
                       change:(NSDictionary *)aChange context:(void *)aContext
{

    //aKeyPath gives us the name of a user default that has changed
    if([aKeyPath isEqualToString:@"goldCount"])
    {
        //we are interested in the new value
        self.goldLabel.text = [NSString stringWithFormat:@"%i",[[aChange objectForKey:@"new"] intValue]];
    }else if([aKeyPath isEqualToString:@"energyCount"])
    {
        self.energyLabel.text = [NSString stringWithFormat:@"%i",[[aChange objectForKey:@"new"] intValue]];
    }

}

添加对 [[NSUserDefaults standardUserDefaults] synchronize] 的调用后;我第二次遇到这个异常:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '( ): An -observeValueForKeyPath:ofObject:change:context: message was received but not handled. Key path: goldCount Observed object: Change: { kind = 1; new = 205; } Context: 0x0'

最佳答案

NSUserDefaults 未记录为与 KVO 兼容,因此无法通过其 key 观察默认值。这可能是崩溃的原因,但如果没有堆栈跟踪,则无法判断。

您可以注册一个通知,通知默认系统的更改:NSUserDefaultsDidChangeNotification .

关于使用 KVO 和延迟选择器观察 NSUserDefaults 时的 iOS exc_bad_access,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20890751/

相关文章:

ios - UIView 底边模式

ios - iOS 中的存储使用情况,objective-c

objective-c - 理解 Objective-C 中的 self

ios - NSUserDefault 在随机时间后被自动清除

ios - Apple App Store 中应用所在的国家/地区

ios - 当用户更改联系人访问权限时,iOS 6 中的应用程序崩溃

ios - Swift - 如何在 iOS 应用中检测 CarPlay 的连接/断开状态?

ios - 当字段来自 sqlite 数据库时点击 didSelectRowAtIndexPath

arrays - 保存包含类数据的表

ios - NSUserDefaults 返回 swift 数组 [String] 而不是 Set<String>