为什么在创buildUIWebView时,清除NSUserDefaults会导致EXC_CRASH?

在我开始之前,我应该告诉你, 这只发生在iOS 5.1。 在最近的更新之前,这从来没有发生过,并且在任何其他版本上都不会发生。 这就是说,这是怎么回事。

当用户注销我的应用程序时,发生的一件事是所有的NSUserDefaults被删除。 我可以使用本SO问题中提出的方法完全删除所有NSUserDefaults ,而不是手动删除每个可能添加到用户默认值的NSUserDefaults

 NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier]; [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain]; 

什么似乎发生虽然,是每次我尝试创build一个UIWebView删除NSUserDefaults ,我得到一个EXC_CRASH (SIGABRT) 。 当我调用[[UIWebView alloc] initWithFrame:frame]时发生崩溃。 奇怪的吧? 完全退出并重新打开应用程序允许再次创buildUIWebView

所以,我设法弄清楚,删除默认值将导致UIWebView问题,但可以肯定的是,我为-[NSUserDefaults setObject:forKey:]添加了一个符号断点。

 -  [NSUserDefaults setObject:forKey:]断点

创build一个UIWebView的确会触发断点。

戳穿崩溃日志给我的例外原因:

 -[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: WebKitLocalStorageDatabasePathPreferenceKey) 

这是堆栈跟踪的开始:

 0 CoreFoundation 0x3340688f __exceptionPreprocess + 163 1 libobjc.A.dylib 0x37bd4259 objc_exception_throw + 33 2 CoreFoundation 0x33406789 +[NSException raise:format:] + 1 3 CoreFoundation 0x334067ab +[NSException raise:format:] + 35 4 CoreFoundation 0x3337368b -[__NSCFDictionary setObject:forKey:] + 235 5 WebKit 0x3541e043 -[WebPreferences _setStringValue:forKey:] + 151 6 UIKit 0x32841f8f -[UIWebView _webViewCommonInit:] + 1547 7 UIKit 0x328418d7 -[UIWebView initWithFrame:] + 75 8 MyApp 0x0007576f + 0 9 UIKit 0x326d4dbf -[UIViewController view] + 51 10 UIKit 0x327347e5 -[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:] + 93 11 UIKit 0x32734783 -[UITabBarController transitionFromViewController:toViewController:] + 31 12 UIKit 0x327340bd -[UITabBarController _setSelectedViewController:] + 301 13 UIKit 0x327bd5d9 -[UITabBarController _tabBarItemClicked:] + 345 

我现在正在做什么,什么工作,只是跟踪我设置的NSUserDefaults键,并在需要时手动删除它们。 但总有一种风险,我可能会忘记一个敏感的关键,所以简单地清除所有的NSUserDefaults让我觉得更明智。 所以,我想知道为什么我不能这样做。 这是一个错误还是我做错了什么?

如果您想了解更多信息,请告诉我! 谢谢。

编辑:做[[NSUserDefaults standardUserDefaults] synchronize]后删除所有的NSUserDefaults没有帮助。

我也看到了这个问题,我想你必须先创build一个UIWebView,然后清除用户默认值才会发生。 一个干净的项目将导致iOS5.1崩溃,这在iOS5.0和更早版本中可以正常工作:

 UIWebView *webView = [[UIWebView alloc] init]; [webView release]; [[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]]; UIWebView *anotherWebView = [[UIWebView alloc] init]; [anotherWebView release]; 

我可以通过这样做来解决崩溃问题,这样可以避免必须记住所有设置键:

 id workaround51Crash = [[NSUserDefaults standardUserDefaults] objectForKey:@"WebKitLocalStorageDatabasePathPreferenceKey"]; NSDictionary *emptySettings = (workaround51Crash != nil) ? [NSDictionary dictionaryWithObject:workaround51Crash forKey:@"WebKitLocalStorageDatabasePathPreferenceKey"] : [NSDictionary dictionary]; [[NSUserDefaults standardUserDefaults] setPersistentDomain:emptySettings forName:[[NSBundle mainBundle] bundleIdentifier]]; 

任何人看到这样做的问题?

这听起来像你正在删除某种私人偏好,这可能是一个新的错误,无论是NSUserDefaults(你不应该能够删除它)或UIWebView(它应该应对缺less的条目)。

你有没有尝试从另一个答案的方法(设置一个空白字典?)。 这是否给出了相同的结果?

如果你得到NSUserDefaults的字典表示,获取所有的键,并遍历这些,删除对象? (让我知道如果你需要一个代码示例)。

这个对我有用

 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSDictionary *userDefaultsDictionary = [userDefaults dictionaryRepresentation]; NSString *strWebDatabaseDirectory = [userDefaultsDictionary objectForKey:@"WebDatabaseDirectory"]; NSString *strWebKitLocalStorageDatabasePathPreferenceKey = [userDefaultsDictionary objectForKey:@"WebKitLocalStorageDatabasePathPreferenceKey"]; [userDefaults removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]]; if (strWebDatabaseDirectory) { [userDefaults setObject:strWebDatabaseDirectory forKey:@"WebDatabaseDirectory"];} if (strWebKitLocalStorageDatabasePathPreferenceKey) { [userDefaults setObject:strWebKitLocalStorageDatabasePathPreferenceKey forKey:@"WebKitLocalStorageDatabasePathPreferenceKey"];} [userDefaults synchronize]; 

更简单的是使用下面的代码:

 [self saveValue:@"" forKey:@"WebKitLocalStorageDatabasePathPreferenceKey"]; [[NSUserDefaults standardUserDefaults] synchronize]; 

这很容易。