初步定为这个问题是 WebView Memory Carsh 的崩溃,这个也是我们项目中崩溃率的最主要点,其中因内存过大造成的 崩溃 也是一直烦着我们。
// Destroy UIWebView
- (void)destroyWebView {
[self.webView loadHTMLString:@"" baseURL:nil];
[self.webView stopLoading];
[self.webView setDelegate:nil];
[self.webView removeFromSuperview];
[self setWebView:nil];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
}
// UIWebViewDelegate Methods
- (void) webViewDidFinishLoad:(UIWebView *)webView {
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDiskImageCacheEnabled"];
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitOfflineWebApplicationCacheEnabled"];
}
当收到内存警告时,同时释放一些
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
然而上述并没有什么用。。。。
进一步分析
以下是我们内存警告的错误日志:
Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x184abeb00 objc_object::release() + 16
1 CoreFoundation 0x1857c0950 -[__NSSingleObjectArrayI dealloc] + 44
2 libobjc.A.dylib 0x184abf38c (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 676
3 UIKitCore 0x1b2eefdb0 -[UIView dealloc] + 964
4 UIKitCore 0x1b2c44754 -[UITableViewCellContentView dealloc] + 76
5 UIKitCore 0x1b2c4444c -[UITableViewCell .cxx_destruct] + 856
6 libobjc.A.dylib 0x184aa4478 object_cxxDestructFromClass(objc_object*, objc_class*) + 148
7 libobjc.A.dylib 0x184ab471c objc_destructInstance + 68
8 libobjc.A.dylib 0x184ab4784 object_dispose + 16
9 UIKitCore 0x1b2aa0fac -[UIResponder dealloc] + 152
10 UIKitCore 0x1b2eefdcc -[UIView dealloc] + 992
11 UIKitCore 0x1b2c33374 -[UITableViewCell dealloc] + 332
12 CoreFoundation 0x185833fc4 cow_cleanup + 112
13 CoreFoundation 0x1857bc2f8 -[__NSArrayM dealloc] + 68
14 CoreFoundation 0x1857ccb78 -[__NSDictionaryM removeAllObjects] + 620
15 UIKitCore 0x1b2c6e8cc -[UITableView _purgeReuseQueues] + 128
16 CoreFoundation 0x18584483c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
17 CoreFoundation 0x185844808 ___CFXRegistrationPost_block_invoke + 64
18 CoreFoundation 0x185843cf8 _CFXRegistrationPost + 392
19 CoreFoundation 0x1858439a4 ___CFXNotificationPost_block_invoke + 96
20 CoreFoundation 0x1857bbb80 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1404
21 CoreFoundation 0x185843430 _CFXNotificationPost + 696
22 Foundation 0x186254ca0 -[NSNotificationCenter postNotificationName:object:userInfo:] + 68
23 UIKitCore 0x1b2a87848 -[UIApplication _performMemoryWarning] + 152
24 UIKitCore 0x1b2a87a34 -[UIApplication _receivedMemoryNotification] + 140
25 libdispatch.dylib 0x18530e484 _dispatch_client_callout + 16
26 libdispatch.dylib 0x1852b182c _dispatch_continuation_pop$VARIANT$mp + 412
27 libdispatch.dylib 0x1852c1b9c _dispatch_source_invoke$VARIANT$mp + 1704
28 libdispatch.dylib 0x1852ba888 _dispatch_main_queue_callback_4CF$VARIANT$mp + 784
29 CoreFoundation 0x185865ce4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
30 CoreFoundation 0x185860bac __CFRunLoopRun + 1964
31 CoreFoundation 0x1858600e0 CFRunLoopRunSpecific + 436
32 GraphicsServices 0x187ad9584 GSEventRunModal + 100
33 UIKitCore 0x1b2a74c00 UIApplicationMain + 212
34 GearBest 0x100e85c34 main (main.m:65)
35 libdyld.dylib 0x18531ebb4 start + 4
注意看
App
收到Memory Warning
后会调用[UIApplication _performMemoryWarning]
然后发通知给相应的页面告知我们需要处理了。
类似这种:
- (void)simulateMemoryWarning {
UIApplication *app = [UIApplication sharedApplication];
if ([app respondsToSelector:@selector(_performMemoryWarning)])
[app performSelector:@selector(_performMemoryWarning)];
}
当我们的程序在第一次收到内存不足警告时,而又没有处理的情况下,内存不足情形依然存在,那么再次向我们程序发出内存不足的警告时,我们的程序将会被杀掉,也就崩溃了。
此时却发现了 是由于 当前
View
没有释放的问题,当前Controller
释放了View
却没有被释放,进一步查找还是View
循环引用的问题,通过一番查找还是将 循环引用的问题解决后,发现这个崩溃率 大大降低(这种bug
平时无法重现)。
当然,本来记录这篇文章的原因是想记录下 WebView Memory Carsh
的解决历程,类似直接加载:
- (void)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
当内容过大时,在 iPhone 6 之前的手机还是容易由于内存不足崩溃的。
所以此时问题并没有解决自己的问题,陆续寻找中 。。。
网友评论