簡體   English   中英

為什么在創建UIWebView時清除NSUserDefaults會導致EXC_CRASH?

[英]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:]添加了一個符號斷點。

 -  [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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM