[英]Why does clearing NSUserDefaults cause EXC_CRASH later when creating a UIWebView?
在開始之前,我應該告訴你, 這只發生在iOS 5.1中。 在最近的更新之前,這從未發生過,並且它仍然不會發生在任何其他版本上。 那就是說,這是正在發生的事情。
當用戶退出我的應用程序時,發生的一件事是所有NSUserDefaults
被刪除。 我不是手動刪除可能添加到用戶默認值的每個鍵,而是使用此SO問題中建議的方法完全刪除所有NSUserDefaults
:
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
但是,在我刪除NSUserDefaults
之后每次嘗試創建UIWebView
,我都會得到一個EXC_CRASH (SIGABRT)
。 當我調用[[UIWebView alloc] initWithFrame:frame]
時發生崩潰。 奇怪吧? 完全退出並重新打開應用程序可以再次創建UIWebView
。
所以,我設法弄清楚刪除默認值會導致UIWebView
問題,但可以肯定的是,我為-[NSUserDefaults setObject:forKey:]
添加了一個符號斷點。
創建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
后執行[[NSUserDefaults standardUserDefaults] synchronize]
沒有幫助。
我也看到了這個問題,我認為你必須首先創建一個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]];
任何人都看到這樣做的任何問題?
聽起來你正在刪除某種私有偏好,這可能是一個新的bug,無論是NSUserDefaults(你不能刪除它)或UIWebView(它應該處理缺少的條目)。
您是否嘗試過其他答案的方法(設置空白字典?)。 這會產生相同的結果嗎?
如果你得到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];
這更容易。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.