ios哪个字符让系统ios崩溃字符

client: 49.76.95.84, server: 0b3d685, time:iOS开发中常见程序崩溃及解决方案
程序崩溃经历
其实在很早之前就想写这篇文章了,一直拖到现在。
程序崩溃经历1 我们公司做的是股票软件,但集成的是第三方的静态库(我们公司和第三方公司合作,他们提供股票的服务,我们付钱)。平时开发测试的时候好好的,结果上线几天发现有崩溃的问题,其实责任大部分在我身上。 我的责任: 过分信赖文档,没进行容错处理,也就是没有对数据进行相应的判断处理。 下面附上代码,说明崩溃的原因
因第三方公司提供的数据错乱导致有时候创建字典的时候个别value为nil才导致的崩溃
#define CStringToOcString(cstr) [NSString stringWithCString:cstr encoding:GBK_ENCODE]
//将每组数据都保存起来
NSMutableArray *returnArray = [NSMutableArray array];
for (int i = 0; i & recordM. i++) {
Withdrawqry_entrust_record *record = (Withdrawqry_entrust_record *)alloca(sizeof(Withdrawqry_entrust_record));
memset(record, 0x00, sizeof(Withdrawqry_entrust_record));
[[recordM objectAtIndex:i] getValue:record];
//崩溃的原因在创建字典的时候,有个别value为nil
(CStringToOcString)
NSDictionary *param =
@&batch_no& : CStringToOcString(record-&batch_no),// 委托批号
@&entrust_no& : CStringToOcString(record-&entrust_no),// 委托编号
@&entrust_type& : @(record-&entrust_type),//委托类别
6 融资委托 7 融券委托 和entrust_bs结合形成融资买入,融资卖出,融券卖出,融券买入
@&entrust_bs& : @(record-&entrust_bs),// 买卖标志
@&stock_account& : CStringToOcString(record-&stock_account),//证券账号
@&gdcode& : CStringToOcString(record-&gdcode),
解决办法,在宏那里做了个判断,若果value为nil,直接赋值为@&&
define CStringToOcString(cstr) [NSString stringWithCString:cstr encoding:GBK_ENCODE] ?
[NSString stringWithCString:cstr encoding:GBK_ENCODE] : @&&
- 程序崩溃经历2
`不做过多的阐述,直接看代码`
//服务器返回的日期格式为
//我要将格式转换成
/** 委托日期 */
NSMutableString *dateStrM = 服务器返回的数据
[dateStrM insertString:@&-& atIndex:4];
[dateStrM insertString:@&-& atIndex:7];
就是上面的代码导致了上线的程序崩溃,搞的我在第二天紧急再上线了一个版本。
为何会崩溃呢?原因是服务器返回的数据错乱了,返回了0。这样字符串的长度就为1,而却插入下标为4的位置,程序必然会崩溃。后来在原本代码上加了一个判断,如下代码:
if (dateStrM.length &= 8) {
[dateStrM insertString:@&-& atIndex:4];
[dateStrM insertString:@&-& atIndex:7];
- 1、不要过分相信服务器返回的数据会永远的正确。
- 2、在对数据处理上,要进行容错处理,进行相应判断之后再处理数据,这是一个良好的习惯。
思考:如何防止存在潜在崩溃方法的崩溃
- 众所周知,Foundation框架里有非常多常用的方法有导致崩溃的潜在危险。对于一个已经将近竣工的项目,若起初没做容错处理又该怎么办?你总不会一行行代码去排查有没有做容错处理吧!-------- 别逗逼了,老板催你明天就要上线了!
- 那有没有一种一劳永逸的方法?无需动原本的代码就可以解决潜在崩溃的问题呢?
拦截存在潜在崩溃危险的方法,在拦截的方法里进行相应的处理,就可以防止方法的崩溃
- 1、通过category给类添加方法用来替换掉原本存在潜在崩溃的方法。
- 2、利用runtime方法交换技术,将方法替换成我们给类添加的新方法。
- 3、利用异常的捕获来防止程序的崩溃,并且进行相应的处理。
- [如果对异常NSException不了解,可以点击查看NSException的介绍。](https://www.jianshu.com/p/05aad21e319e)
创建一个工具类AvoidCrash,来处理方法的交换,获取会导致崩溃代码的具体位置,在控制台输出错误的信息......
- [代码中有正则表达式的知识点,不熟悉正则表达式的朋友们点我](https://www.jianshu.com/p/b25b05ef170d)
`AvoidCrash.h`
// AvoidCrash.h
// AvoidCrash
// Created by mac on 16/9/21.
// Copyright ? 2016年 chenfanfang. All rights reserved.
//通知的名称,若要获取详细的崩溃信息,请监听此通知
define AvoidCrashNotification @&AvoidCrashNotification&
define AvoidCrashDefaultReturnNil @&This framework default is to return nil.&
define AvoidCrashDefaultIgnore @&This framework default is to ignore this operation to avoid crash.&
@interface AvoidCrash : NSObject
become effective . You can call becomeEffective method in AppDelegate didFinishLaunchingWithOptions开始生效.你可以在AppDelegate的didFinishLaunchingWithOptions方法中调用becomeEffective方法
(void)becomeE
(void)exchangeClassMethod:(Class)anClass method1Sel:(SEL)method1Sel method2Sel:(SEL)method2S
(void)exchangeInstanceMethod:(Class)anClass method1Sel:(SEL)method1Sel method2Sel:(SEL)method2S
(NSString *)getMainCallStackSymbolMessageWithCallStackSymbolStr:(NSString *)callStackSymbolS
(void)noteErrorWithException:(NSException *)exception defaultToDo:(NSString *)defaultToDo;
`AvoidCrash.m`
// AvoidCrash.m
// AvoidCrash
// Created by mac on 16/9/21.
// Copyright ? 2016年 chenfanfang. All rights reserved.
import &AvoidCrash.h&
//category
import &NSArray+AvoidCrash.h&
import &NSMutableArray+AvoidCrash.h&
import &NSDictionary+AvoidCrash.h&
import &NSMutableDictionary+AvoidCrash.h&
import &NSString+AvoidCrash.h&
import &NSMutableString+AvoidCrash.h&
define AvoidCrashSeparator @&================================================================&
define AvoidCrashSeparatorWithFlag @&========================AvoidCrash Log==========================&
define key_errorName @&errorName&
define key_errorReason @&errorReason&
define key_errorPlace @&errorPlace&
define key_defaultToDo @&defaultToDo&
define key_callStackSymbols @&callStackSymbols&
define key_exception @&exception&
@implementation AvoidCrash
开始生效(进行方法的交换)
(void)becomeEffective {
static dispatch_once_t onceT
dispatch_once(&onceToken, ^{
[NSArray avoidCrashExchangeMethod];
[NSMutableArray avoidCrashExchangeMethod];
[NSDictionary avoidCrashExchangeMethod];
[NSMutableDictionary avoidCrashExchangeMethod];
[NSString avoidCrashExchangeMethod];
[NSMutableString avoidCrashExchangeMethod];
类方法的交换@param anClass 哪个类@param method1Sel 方法1@param method2Sel 方法2
*/(void)exchangeClassMethod:(Class)anClass method1Sel:(SEL)method1Sel method2Sel:(SEL)method2Sel {
Method method1 = class_getClassMethod(anClass, method1Sel);
Method method2 = class_getClassMethod(anClass, method2Sel);
method_exchangeImplementations(method1, method2);
对象方法的交换@param anClass 哪个类@param method1Sel 方法1@param method2Sel 方法2
*/(void)exchangeInstanceMethod:(Class)anClass method1Sel:(SEL)method1Sel method2Sel:(SEL)method2Sel {
Method method1 = class_getInstanceMethod(anClass, method1Sel);
Method method2 = class_getInstanceMethod(anClass, method2Sel);
method_exchangeImplementations(method1, method2);
获取堆栈主要崩溃精简化的信息&根据正则表达式匹配出来&@param callStackSymbolStr 堆栈主要崩溃信息@return 堆栈主要崩溃精简化的信息
(NSString *)getMainCallStackSymbolMessageWithCallStackSymbolStr:(NSString *)callStackSymbolStr {
//mainCallStackSymbolMsg的格式为 +[类名 方法名] 或者 -[类名 方法名]
__block NSString *mainCallStackSymbolMsg =
//匹配出来的格式为 +[类名 方法名] 或者 -[类名 方法名]
NSString *regularExpStr = @&[-\+]\[.+\]&;
NSRegularExpression *regularExp = [[NSRegularExpression alloc] initWithPattern:regularExpStr options:NSRegularExpressionCaseInsensitive error:nil];
[regularExp enumerateMatchesInString:callStackSymbolStr options:NSMatchingReportProgress range:NSMakeRange(0, callStackSymbolStr.length) usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) {
if (result) {
mainCallStackSymbolMsg = [callStackSymbolStr substringWithRange:result.range];
*stop = YES;
return mainCallStackSymbolM
提示崩溃的信息(控制台输出、通知)@param exception 捕获到的异常@param defaultToDo 这个框架里默认的做法
(void)noteErrorWithException:(NSException *)exception defaultToDo:(NSString *)defaultToDo {
//堆栈数据
NSArray *callStackSymbolsArr = [NSThread callStackSymbols];
//获取在哪个类的哪个方法中实例化的数组 字符串格式 -[类名 方法名] 或者 +[类名 方法名]
NSString *mainCallStackSymbolMsg = [AvoidCrash getMainCallStackSymbolMessageWithCallStackSymbolStr:callStackSymbolsArr[2]];
if (mainCallStackSymbolMsg == nil) {
mainCallStackSymbolMsg = @&崩溃方法定位失败,请您查看函数调用栈来排查错误原因&;
NSString *errorName = exception.
NSString *errorReason = exception.
//errorReason 可能为 -[__NSCFConstantString avoidCrashCharacterAtIndex:]: Range or index out of bounds
//将avoidCrash去掉
errorReason = [errorReason stringByReplacingOccurrencesOfString:@&avoidCrash& withString:@&&];
NSString *errorPlace = [NSString stringWithFormat:@&Error Place:%@&,mainCallStackSymbolMsg];
NSString *logErrorMessage = [NSString stringWithFormat:@&\n\n%@\n\n%@\n%@\n%@\n%@\n\n%@\n\n&,AvoidCrashSeparatorWithFlag, errorName, errorReason, errorPlace, defaultToDo, AvoidCrashSeparator];
NSLog(@&%@&, logErrorMessage);
NSDictionary *errorInfoDic = @{
key_errorName : errorName,
key_errorReason : errorReason,
key_errorPlace : errorPlace,
key_defaultToDo : defaultToDo,
key_exception : exception,
key_callStackSymbols : callStackSymbolsArr
//将错误信息放在字典里,用通知的形式发送出去
[[NSNotificationCenter defaultCenter] postNotificationName:AvoidCrashNotification object:nil userInfo:errorInfoDic];
创建一个NSDictionary的分类,来防止创建一个字典而导致的崩溃。
`NSDictionary+AvoidCrash.h`
// NSDictionary+AvoidCrash.h
// AvoidCrash
// Created by mac on 16/9/21.
// Copyright ? 2016年 chenfanfang. All rights reserved.
@interface NSDictionary (AvoidCrash)
(void)avoidCrashExchangeM
`NSDictionary+AvoidCrash.m`
在这里先补充一个知识点: 我们平常用的快速创建字典的方式@{key : value}; 其实调用的方法是`dictionaryWithObjects:forKeys:count:` 而该方法可能导致崩溃的原因为: key数组中的key或者objects中的value为空
// NSDictionary+AvoidCrash.m
// AvoidCrash
// Created by mac on 16/9/21.
// Copyright ? 2016年 chenfanfang. All rights reserved.
import &NSDictionary+AvoidCrash.h&
import &AvoidCrash.h&
@implementation NSDictionary (AvoidCrash)
(void)avoidCrashExchangeMethod {
[AvoidCrash exchangeClassMethod:self method1Sel:@selector(dictionaryWithObjects:forKeys:count:) method2Sel:@selector(avoidCrashDictionaryWithObjects:forKeys:count:)];
(instancetype)avoidCrashDictionaryWithObjects:(const id _Nonnull __unsafe_unretained *)objects forKeys:(const id _Nonnull __unsafe_unretained *)keys count:(NSUInteger)cnt {
id instance =
instance = [self avoidCrashDictionaryWithObjects:objects forKeys:keys count:cnt];
@catch (NSException *exception) {
NSString *defaultToDo = @&This framework default is to remove nil key-values and instance a dictionary.&;
[AvoidCrash noteErrorWithException:exception defaultToDo:defaultToDo];
//处理错误的数据,然后重新初始化一个字典
NSUInteger index = 0;
_Nonnull __unsafe_unretained newObjects[cnt];
_Nonnull __unsafe_unretained newkeys[cnt];
for (int i = 0; i & i++) {
if (objects[i] && keys[i]) {
newObjects[index] = objects[i];
newkeys[index] = keys[i];
instance = [self avoidCrashDictionaryWithObjects:newObjects forKeys:newkeys count:index];
@finally {
来看下防止崩溃的效果
- 正常情况下,若没有我们上面的处理,如下代码就会导致崩溃
NSString *nilStr =
NSDictionary *dict = @{
@&key& : nilStr
崩溃截图如下:
![崩溃截图.png](https://upload-images.jianshu.io/upload_images/dbad6c12d275b2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 若通过如上的处理,就可以避免崩溃了
[AvoidCrash becomeEffective];
控制台的输出截图如下
![防止崩溃控制台输出的信息.png](https://upload-images.jianshu.io/upload_images/2b50e13cbd022.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 若想要获取到崩溃的详细信息(我们可以监听通知,通知名为:AvoidCrashNotification):可以将这些信息传到我们的服务器,或者在集成第三方收集Crash信息的SDK中自定义信息,这样我们就可以防止程序的崩溃,并且又得知哪些代码导致了崩溃。
//监听通知:AvoidCrashNotification, 获取AvoidCrash捕获的崩溃日志的详细信息
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dealwithCrashMessage:) name:AvoidCrashNotification object:nil];
(void)dealwithCrashMessage:(NSNotification *)note {
//注意:所有的信息都在userInfo中
//你可以在这里收集相应的崩溃信息进行相应的处理(比如传到自己服务器)
NSLog(@&\n\n在AppDelegate中 方法:dealwithCrashMessage打印\n\n\n\n\n%@\n\n\n\n&,note.userInfo);
附上一张截图查看通知中携带的崩溃信息是如何的
![AvoidCrashNotification通知的监听.png](https://upload-images.jianshu.io/upload_images/bc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 程序崩溃有崩溃的好处,就是让开发者快速认识到自己所写的代码有问题,这样才能及时修复BUG,当然这种好处只限于在开发阶段。若一个上线APP出现崩溃的问题,这问题可就大了(老板不高兴,后果很严重)。
- 个人建议:在发布的时候APP的时候再用上面介绍的方法来防止程序的崩溃,在开发阶段最好不用。
- 上面只是举个例子,更多防止崩溃的方法请查看Github [AvoidCrash](https://github.com/chenfanfang/AvoidCrash),这是我最近写的一个框架,大家可以集成到自己的项目中去,在发布APP的时候在appDelegate的didFinishLaunchingWithOptions中调用方法`[AvoidCrash becomeEffective];`即可,若要获取崩溃信息,监听通知即可。
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[AvoidCrash becomeEffective];
//监听通知:AvoidCrashNotification, 获取AvoidCrash捕获的崩溃日志的详细信息
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dealwithCrashMessage:) name:AvoidCrashNotification object:nil];
return YES;
(void)dealwithCrashMessage:(NSNotification *)note {
//注意:所有的信息都在userInfo中
//你可以在这里收集相应的崩溃信息进行相应的处理(比如传到自己服务器)
NSLog(@&\n\n在AppDelegate中 方法:dealwithCrashMessage打印\n\n\n\n\n%@\n\n\n\n&,note.userInfo);
- 同时希望大家能够提出更多容易导致崩溃的方法,我好添加到AvoidCrash框架中,当然也欢迎大家和我一起维护这个框架。
- 最后,希望大家给上你们珍贵的一票(帅哥、美女,给个star哈)。
[AvoidCrash](https://github.com/chenfanfang/AvoidCrash)更新
- 修复上一个版本部分方法不能拦截崩溃的BUG,具体修复哪些可以查看issues和简书上的留言。
- 优化崩溃代码的定位,定位崩溃代码更加准确。
- 增加对KVC赋值防止崩溃的处理。
- 增加对NSAttributedString防止崩溃的处理
- 增加对NSMutableAttributedString防止崩溃的处理
- 修复在键盘弹出状态下,按Home键进入后台会导致崩溃的bug。
- 新增防止崩溃(NSArray、NSMutableArray) - (NSArray *)objectsAtIndexes:(NSIndexSet *)indexes
- 处理数组的类簇问题,提高兼容性,不论是由于array[100]方式,还是[array objectAtIndex:100]方式 获取数组中的某个元素操作不当而导致的crash,都能被拦截防止崩溃。
- 上一个版本只能防止array[100]导致的崩溃,不能防止[array objectAtIndex:100]导致的崩溃。
- 统一对线程进行处理,监听通知AvoidCrashNotification后,不论是在主线程导致的crash还是在子线程导致的crash,监听通知的方法统一在&主线程&中。
- 上一个版本中,在哪个线程导致的crash, 则监听通知的方法就在哪个线程中。
- 新增防止崩溃 (NSArray、NSMutableArray)
`- (void)getObjects:(__unsafe_unretained id
_Nonnull *)objects range:(NSRange)range`当前位置:
> 帖子正文
收到iOS8崩溃信息阿拉伯字符怎么办 这样即可解决
本帖有隐藏内容,需要回复楼主之后才能查看哦~
谢谢楼主,楼主威武!
最新评论(14)
发表于: 22:04:55
发表于: 22:08:30
发表于: 22:08:32
发表于: 20:59:37
路过 我看看
发表于: 13:24:04
发表于: 23:04:01
uyuyuyuyuyuyuyuyuyuyuyuyuyuyuyu
发表于: 04:01:09
u 东莞系统
发表于: 16:56:05
ssssssssssssss
发表于: 08:27:18
发表于: 14:18:06
发表于: 15:48:20
内容😂😂😂😂
发表于: 22:18:44
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
发表于: 15:14:26
hgfhgfhgfhggfhfgh
发表于: 15:42:15
发表于: 17:30:53
此贴已被删除
您需要注册登录后,才能回帖哦!
参考价:¥2788
上市时间:2017.09
上市时间:2017.11
上市时间:2017.04
上市时间:2017.12
上市时间:2017.11
上市时间:2017.09
上市时间:2017.11
上市时间:2018.02
上市时间:2017.10
上市时间:2017.09
上市时间:2018.02
上市时间:2017.11
上市时间:2017.09
上市时间:2017.11
上市时间:2017.12
您已经签到了,请明天再来吧!他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 ios崩溃字符 的文章

 

随机推荐