问题描述
这可能是iOS 9.3(发布)中的一个糟糕错误。
This might be an awful bug in iOS 9.3 (release).
将单个观察者添加到 [NSUserDefaults standardUserDefaults]
我注意到响应方法 -observeValueForKeyPath:ofObject:change:context:
被多次调用。
When adding a single observer to [NSUserDefaults standardUserDefaults]
I've noticed that the responding method -observeValueForKeyPath:ofObject:change:context:
is called multiple times.
在下面的简单示例中,每次按下一次UIButton时,observeValueForKeyPath会触发两次。在更复杂的例子中,它会发射更多次。它仅出现在iOS 9.3上(包括SIM卡和设备)。
In the simple example below, every time a UIButton is pressed once, observeValueForKeyPath fires twice. In more complicated examples it fires even more times. It is only present on iOS 9.3 (both on sim and devices).
这显然会对应用程序造成严重破坏。其他人经历过同样的事情吗?
This can obviously wreak havoc on an app. Anyone else experiencing the same?
// ViewController.m (barebones, single view app)
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"viewDidLoad");
[[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"SomeKey" options:NSKeyValueObservingOptionNew context:NULL];
}
- (IBAction)buttonPressed:(id)sender {
NSLog(@"buttonPressed");
[[NSUserDefaults standardUserDefaults] setInteger:1 forKey:@"SomeKey"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
NSLog(@"observeValueForKeyPath: %@", keyPath);
}
推荐答案
是的我遇到这个问题好吧,它似乎是一个错误,下面是我正在使用的一个快速解决方法,直到这是固定的。我希望它有所帮助!
Yes I am experiencing this as well and it seems to be a bug, below is a quick workaround I’m using for the moment until this is fixed. I hope it helps!
另外要澄清一下,因为iOS 7 KVO在NSUserDefaults上工作得非常好,而且它似乎是Matt所说的关键值可观察的,它是明确的在iOS 9.3 SDK中用NSUserDefaults.h编写:对于存储在其中的任何密钥,可以使用键值观察来观察NSUserDefault。
Also to clarify, since iOS 7 KVO has been working great with NSUserDefaults and it certainly appears to be key value observable as Matt stated, it is explicitly written in NSUserDefaults.h in the iOS 9.3 SDK: "NSUserDefaults can be observed using Key-Value Observing for any key stored in it."
#include <mach/mach.h>
#include <mach/mach_time.h>
@property uint64_t newTime;
@property uint64_t previousTime;
@property NSString *previousKeyPath;
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
//Workaround for possible bug in iOS 9.3 SDK that is causing observeValueForKeyPath to be called multiple times.
newTime = mach_absolute_time();
NSLog(@"newTime:%llu", newTime);
NSLog(@"previousTime:%llu", previousTime);
//Try to avoid duplicate calls
if (newTime > (previousTime + 5000000.0) || ![keyPath isEqualToString:previousKeyPath]) {
if (newTime > (previousTime + 5000000.0)) {
NSLog(@"newTime > previousTime");
previousTime = newTime;
NSLog(@"newTime:%llu", newTime);
NSLog(@"previousTime:%llu", previousTime);
}
if (![keyPath isEqualToString:previousKeyPath]) {
NSLog(@"new keyPath:%@", keyPath);
previousKeyPath = keyPath;
NSLog(@"previousKeyPath is now:%@", previousKeyPath);
}
//Proceed with handling changes
if ([keyPath isEqualToString:@"MyKey"]) {
//Do something
}
}
}
这篇关于KVO在iOS 9.3中被破坏了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!