iOS应用内存占用过高崩溃

7,518 阅读2分钟

题记

测试过程中发现一个问题:个别商品,进到商详页,应用跑着跑着突然Crash。打开断点调试,也没有具体崩溃的地方,系统就报了这个错误:Message from debugger: Terminated due to memory issue.

调查

刚开始以为是加载播放视频的问题,可是其他商品也有视频。注释掉视频播放还是会崩溃。 而且只有个别商品、在真机6p机型上崩溃😖。 对比排查最后确定,是UIWebVIew加载HTML商详导致程序crash。

原因

加载商详描述信息的实现方法有问题。用的UIWebVIew直接加载的HTML描述信息。 原来的实现方式:商详页整个TableView。描述信息是一个cell,cell里面是一个webVIew,直接用webView加载HTML描述文件。加载完成之后,更新cell高度==webView.contentSize.height;

之前为啥没出现类似的崩溃? 因为这个商品描述信息太多了,加载完成之后发现webVIew的ContentSize.height = 17434!!!! 这也太大了,在App上确实不能这么干啊。一般商品、最新机型还能接受。但是6p 运行内存1G,屏幕又大,打开应用一多,内存直接就崩了。

尝试解决办法

1.更换UIWebVIew 为 WKWebView 因为UIWebVIew本身就比较耗内存,所以更换了WKWebView。 但是在iOS 10.3.1系统上会出现加载白屏的情况,其他系统没出现呢,很奇怪。 不只是不是系统的bug。(因为iOS10系统出现过很多bug。比如:系统bug 等等很多。) 又赶上上线,就放弃了这个方法。 PS:在之后系统上直接处理下滚动方式,也可以解决,就在iOS 10.3系统上不行。不知是不是之后系统处理优化了滚动方式。

-(void)scrollViewDidScroll:(UIScrollView *)scrollView  {
}

2.因为应用会先报内存警告,然后Crash。 所以试着在报内存警告的时候释放下内存。按照网上的方法,

//内存警告了
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    NSLog(@"来啦 小老弟  内存警告");
    
    [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDiskImageCacheEnabled"];
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitOfflineWebApplicationCacheEnabled"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

//对应VC里会内存警告
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    NSLog(@"内存警告了哈  UIApplicationDidReceiveMemoryWarningNotification ");
    
    [[NSURLCache sharedURLCache] removeAllCachedResponses];
    [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDiskImageCacheEnabled"];
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitOfflineWebApplicationCacheEnabled"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

这种类似的方法确实没啥用,还是会崩溃。

3.更改实现方法 将商品描述信息cell高度固定,就一个屏幕高,然后监听滑动,当滚动到商品描述时,就让webView滚动。当webVIew滚动到顶、底部的时候,在让外面的tableView滚动。 具体实现方法参考:github.com/xuning0/Scr…