几个系统级崩溃问题和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为非空时再返回。
if(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];

“`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值