几个系统级崩溃问题和h5加载页面崩溃问题及解决方案

简介: 几个系统级崩溃问题和h5加载页面崩溃问题及解决方案

众所周知系统级崩溃定位不到代码的具体函数,一般都是内存释放时异常,空指针,越界访问问题。再加上苹果应用在切换到后台,杀线程问题,io资源在后台不可以申请问题(当在后台连续断网10分钟,就是定位应用的线程也会被杀掉)。这都是苹果应用一般比安卓应用运行流畅,而开发者对问题定位和线程守护感到头疼的问题。

第一个问题:

h5页面在加载出来前来回多次进入又退出h5页面,导致崩溃。

原因:

第三方库WebViewJavascriptBridgeBase没有进行对是否在主线程进行判断。

修改方案:

if ([NSThread isMainThread])
{
[self _evaluateJavascript:javascriptCommand];
}
else
{
dispatch_sync(dispatch_get_main_queue(), ^{
if(javascriptCommand.length == 0)
{
return;
}
[self _evaluateJavascript:javascriptCommand];
});
}

第二个问题:

应用启动启动期间,调用了 dispatch_sync回主线程而引起崩溃。注意:app启动时,[NSThread isMainThread]判断是在子线程,也不能会主线程,不然崩溃。

当应用启后,不能在主线程里刷新UI。

方案:

在应用启动后判断是否在主线程,返回主线程。但是在应用启动过程中,禁止使用回主线程。

// this makes sure the change notification happens on the MAIN THREAD
if ([NSThread isMainThread])
{
}
else
{
dispatch_sync(dispatch_get_main_queue(), ^{
});
}

第三个问题:

在页面控制器中注册了通知,离开页面(不再重用)并期望销毁页面(使用不当导致实际上没有销毁页面,如:常规使用定时器),没有移除通知。当再次申请相同的页面时,有概率性出现通知相关的崩溃。

这个问题是困惑了我们几年的问题,大都报通知事件没有注册。崩溃栈指向的代码都是很正常的代码。这个问题我们最近两个月才发现这个根本原因。若你的技术水平做不到能真正的销毁页面,就在离开页面就移除通知。页面销毁时调用- (void)dealloc函数。只要你使用定时器,不特别处理,就是你把定时器指针置为nil,所在页面也销毁不了。所以实时移除注册的通知很有必要,也最简单。

解决方案:

离开页面就移除通知。若有特别的页面离开后,可能监控通知,自己特别处理,保证它真的不再使用时,在适当时候移除通知。


第四个问题:

在子线程里发送通知,在通知处理函数中不会主线程直接刷新ui引起系统崩溃。

解决方案:

在子线程里发送通知前,判断是否在主线程,若不在主线线程就回主线程,然后再发送通知。这样即好统一管理,实现又简单。

if ([NSThread isMainThread])
{
if(self.offLineSuccessBlock != nil)
{
self.offLineSuccessBlock(YES);
}
self.hitOnOffLineTime = 0;
}
else
{
dispatch_sync(dispatch_get_main_queue(), ^{
if (self.hitOnOffLineTime > 0)
{
if(self.offLineSuccessBlock != nil)
{
self.offLineSuccessBlock(YES);
}
self.hitOnOffLineTime = 0;
}
});
}

第五个问题:

block为空时返回崩溃问题。

解决方案:

在block处理产生时记录一个时间和block指针。当block返回受限保证这个记录时间有效并且block为非空时再返回。

i

f(self.hitOnOffLineTime > 0)
{
if(self.offLineSuccessBlock != nil)
{
if ([NSThread isMainThread])
{
if(self.offLineSuccessBlock != nil)
{
self.offLineSuccessBlock(YES);
}
self.hitOnOffLineTime = 0;
}
else
{
dispatch_sync(dispatch_get_main_queue(), ^{
if (self.hitOnOffLineTime > 0)
{
if(self.offLineSuccessBlock != nil)
{
self.offLineSuccessBlock(YES);
}
self.hitOnOffLineTime = 0;
}
});
}
}
else
{
self.hitOnOffLineTime = 0;
}
}

第六个问题:

创建一个线程,在这个线程体内开始部分立刻起了一个线程。文件描述符耗尽,引起系统崩溃。

解决方案:

禁止这种无等待连环起线程的错误行为。

第七个问题:

插入一个空对象到可变数组,或初始化数组是的元素为nil.

如下崩溃:

ModalName: 文件日志, ErrorLevel: Error, Function: UncaughtExceptionHandler, Line: 215, Format: <- 2017-03-31 11:02:48 ->[ Uncaught Exception ]
Name: NSInvalidArgumentException, Reason: *** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]
[ Fe Symbols Start ]
0   CoreFoundation                      0x000000018894eff0 <redacted> + 148
1   libobjc.A.dylib                     0x00000001873b0538 objc_exception_throw + 56
2   CoreFoundation                      0x00000001888302c8 <redacted> + 308
3   CoreFoundation                      0x0000000188942c38 <redacted> + 36
4   CoreFoundation                      0x0000000188832cbc <redacted> + 36
5   OutdoorClub                         0x0000000100133d58 -[ODCCurrentPathLocationDataSingleObject saveCoordateWithFileName:lastLocationOperateModel:] + 308
6   OutdoorClub                         0x0000000100132c90 -[ODCCurrentPathLocationDataSingleObject readmis] + 1672
7   OutdoorClub                         0x0000000100132324 __50-[ODCCurrentPathLocationDataSingleObject initData]_block_invoke + 100
8   OutdoorClub                         0x00000001003c2a10 +[NSTimer(YYAdd) _yy_ExecBlock:] + 148
9   Foundation                          0x0000000189443760 __NSFireTimer + 88
10  CoreFoundation                      0x00000001888fda9c <redacted> + 28
11  CoreFoundation                      0x00000001888fd7a0 <redacted> + 856
12  CoreFoundation                      0x00000001888fd060 <redacted> + 244
13  CoreFoundation                      0x00000001888fac84 <redacted> + 1484
14  CoreFoundation                      0x000000018882ad94 CFRunLoopRunSpecific + 424
15  GraphicsServices                    0x000000018a294074 GSEventRunModal + 100
16  UIKit                               0x000000018eae3130 UIApplicationMain + 208
17  OutdoorClub                         0x000000010014853c main + 124
18  libdyld.dylib                       0x000000018783959c <redacted> + 4
[ Fe Symbols End ]

引起崩溃的代码:

这个是上面调用的代码

[self.currentPathLocationDataArray addObject:self.locationOperateModel];
[self saveCoordateWithFileName:ODCCoordatesFileName lastLocationOperateModel:self.currentPathLocationDataArray[self.currentPathLocationDataArray.count-1]];

这个是崩溃的代码。

NSMutableArray *arr = [NSMutableArray arrayWithObject:lastLocationOperateModel];

它是怎么崩溃的呢?因为self.currentPathLocationDataArray为nil,加入的对象,再取出,当然还是nil了,你再初始化数组当然就崩溃了。
修改方法:
if(self.currentPathLocationDataArray == nil)
{
    self.currentPathLocationDataArray = [NSMutableArray array];
}
[self.currentPathLocationDataArray addObject:self.locationOperateModel];
目录
相关文章
|
1月前
|
存储 监控 iOS开发
iOS应用崩溃了,如何通过崩溃手机连接电脑查找日志方法
在iOS应用开发过程中,调试日志和奔溃日志是开发者必不可少的工具。当iOS手机崩溃时,我们可以连接电脑并使用Xcode Console等工具来查看日志。然而,这种方式可能不够方便,并且处理奔溃日志也相当繁琐。克魔助手的出现为开发者带来了极大的便利,本文将详细介绍其功能和使用方法。 克魔助手会提供两种日志,一种是实时的,一种的是崩溃的。(由于崩溃日志的环境很麻烦,目前只展示实时日志操作步骤)
|
1月前
|
安全 Linux 开发者
⭐⭐⭐⭐⭐Linux C/C++ 进程崩溃诊断以及有效数据收集:解锁代码问题快速定位与修复的方法
⭐⭐⭐⭐⭐Linux C/C++ 进程崩溃诊断以及有效数据收集:解锁代码问题快速定位与修复的方法
159 1
|
1月前
|
监控 JavaScript C++
监控游戏c/c++的崩溃的解决方案
监控游戏c/c++的崩溃的解决方案
59 0
|
1月前
|
JavaScript IDE Java
bugly崩溃排查3:观察是谁调用了崩溃函数
bugly崩溃排查3:观察是谁调用了崩溃函数
27 0
|
10月前
|
存储 监控 数据可视化
01.崩溃捕获设计实践方案
01.崩溃捕获设计实践方案
147 3
|
9月前
|
安全 程序员 API
向大厂看齐!为自己的程序增加自动转储的功能!
向大厂看齐!为自己的程序增加自动转储的功能!
|
10月前
|
Web App开发 Java 开发工具
systrace: 系统级跟踪工具的解析
systrace是Android4.1版本之后推出的,对系统Performance分析的工具,该工具结合Android 内核的数据,最终会生产html文件。 systrace的功能包括跟踪系统的I/O操作、内核工作队列、CPU负载以及Android各个子系统的运行状况等
|
11月前
|
Java 编译器 应用服务中间件
几行代码就可以把系统高崩溃;
几行代码就可以把系统高崩溃;
73 0
|
存储 测试技术
kindle 应用程序出错,无法启动选定的应用程序,请重试。问题排查过程及处理方案。...
kindle 应用程序出错,无法启动选定的应用程序,请重试。问题排查过程及处理方案。...
378 0
|
前端开发 Devops 程序员
浅谈移动端的崩溃分析
介绍iOS,Android移动端的崩溃分析的基本原理与实现方式。