糖果派对官方网站_可以赌钱的糖果游戏_手机版
ios多如牛毛Crash

ios多如牛毛Crash

作者:网络编程    来源:未知    发布时间:2020-04-26 20:10    浏览量:

乘势公司嘟嘟牛app客商数量多了起来,崩溃的难点也多了四起,近年来这段时间终于得空,集中时间管理了眨眼间间拆家荡产的难点,现总计一下,希望对大家持有助于。

代码下载

1.NSInvalidArgumentException 异常

并发这种非常的案由通常是在不得以现身nil数据的时候传出了nil,举个例子在成立NSDictionary的时候值传入了nil就能出现这种崩溃错误,如若必需传空需求把nil对象转成NSNull才得以确定保证不出新这种错误,有3种方案能够解决该难点,如下:

方案一:后台在回来数据的时候举办校验,对空值进行拍卖。不过在档案的次序中有个别空值是有独特的用场,此种方案不可行。

方案二:在调换到NSDictionary的时候,对后台重回的数据开展校验,把空值调换来NSNull对象。方案可行,可是需求对现成代码做大的转移,每回改造的时候都急需张开校验,太辛苦。业务迅猛发展时期,这样做本金太高。

方案三:有未有一种无须变动现成代码又能缓和该难题吗?答案是部分,能够应用Objective-C的runtime来解决该难题。

NSDictionary插入nil对象会以致崩溃,可是插入NSNull对象是不会诱致崩溃的,只要利用runtime的Swizzle Method把nil对象给调换来NSNull对象就足以把该难点给化解了。创造一个NSDictionary的门类,利用runtime的Swizzle Method来替换系统的秘诀。源码完结能够参见Glow团队卷入的NSDictionary+NilSafe(Github上可下载到卡塔尔, 现截取在那之中的部分代码如下:

+ (instancetype)gl_dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt {
    id safeObjects[cnt];
    id safeKeys[cnt];
    NSUInteger j = 0;
    for (NSUInteger i = 0; i < cnt; i++) {
        id key = keys[i];
        id obj = objects[i];
        if (!key) {
            continue;
        }
        if (!obj) {
            obj = [NSNull null];
        }
        safeKeys[j] = key;
        safeObjects[j] = obj;
        j++;
    }
    return [self gl_dictionaryWithObjects:safeObjects forKeys:safeKeys count:j];
}

杀手 NO.1

现身这一个crash的开始和结果有成都百货上千,选择了崩溃次数比较多的crash。

ios多如牛毛Crash。crash 日志1-1

-[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[3]

bb电子糖果派对,crash日志获得了,怎么复现该现象呢?大家来看initWithObjects:forKeys:count:,猜度一下应该是NSDictionary开始化时的难点,在看前面的提醒attempt to insert nil object,当时就可以做一个困惑,应该是NSDictionary初步化时插入nil对象产生的百般。上边大家写一段代码来证实一下:

NSString *password = nil;NSDictionary *dict = @{ @"userName": @"bruce", @"password": password };NSLog(@"dict is : %@", dict);

运作过后,崩溃音信如下:

bb电子糖果派对 1Crash 日志1-1

上边的咽气音讯认证了作者们的猜度。从崩溃日志记录中,查询到该难点的倒台记录有33条(总崩溃记录304条),占10.85%,崩溃率相比较高。为啥会现身这种现象呢?如何解决那样的crash呢?

崩溃率高的因由是因为本人的框架中运用了去model化的规划观念,不会把后台重回的多少转换到model,而是通过多个reformer机制转变来NSDictionary方式,提需要目标对象使用,在调换到NSDictionary的历程中,后台重返的数量有的时候可能为空,就能够促成插入nil对象,进而诱致crash。

有3种方案可以消亡该难点,如下:

方案一:后台在回来数据的时候举行校验,对空值进行拍卖。但是在品种中大抵空值是有特出的用场,此种方案不可行。

方案二:在调换到NSDictionary的时候,对后台重临的数据开展校验,把空值转变到NSNull对象。方案可行,但是须求对现存代码做大的变动,每趟退换的时候都必要展开校验,太难为。业务高速发展时期,那样做本金太高。

方案三:有未有一种无须变动现存代码又能消释该难点吗?答案是有些,能够使用Objective-C的runtime来减轻该难点。

NSDictionary插入nil对象会招致崩溃,不过插入NSNull对象是不会促成崩溃的,只要选择runtime的Swizzle Method把nil对象给转换到NSNull对象就足以把该难题给搞定了。创立多个NSDictionary的种类,利用runtime的Swizzle Method来替换系统的情势。源码达成能够参照Glow团队卷入的NSDictionary+NilSafe(Github上可下载到卡塔尔国, 所有的事源码会在篇章最终提供,现截取当中的一对代码如下:

+ (instancetype)gl_dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt { id safeObjects[cnt]; id safeKeys[cnt]; NSUInteger j = 0; for (NSUInteger i = 0; i < cnt; i++) { id key = keys[i]; id obj = objects[i]; if  { continue; } if  { obj = [NSNull null]; } safeKeys[j] = key; safeObjects[j] = obj; j++; } return [self gl_dictionaryWithObjects:safeObjects forKeys:safeKeys count:j];}

** crash 日志1-2 **

data parameter is nil

经过日记音信,能够把崩溃难点一定到参数为nil的情事,在看了下旅社的日记新闻,把难题一定到了NSJSONSerialization种类化的时候,传入data为nil,形成的垮台。为了证实是还是不是该难点,我写了一段代码做了下验证:

NSData *data = nil;NSError *error;NSDictionary *orginDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];NSLog(@"originDict is : %@", orginDict);

运作后,崩溃消息如下:

bb电子糖果派对 2Crash日志 1-2

本条主题素材比较好解决,在体系化的时候,统三星入判别,剖断data是否nil就能够。

** crash 日志1-3 **

unrecognized selector sent to instance 0x15d23910

招致这条崩溃的缘故,想必咱们都相比较熟谙了,正是三个类调用了三个不设有的秘籍,形成的崩溃。解决那样的标题,能够在写多个办法的时候,判断一下其类的品类,不适合项目标不让其调用,也得以动用runtime对平淡无奇的点子调用做一下破绽比超多包容。例如自个儿那边平时会见世那样的倒台:

-[__NSCFConstantString objectForKeyedSubscript:]: unrecognized selector sent to instance 0x1741af420-[NSNull length]: unrecognized selector sent to instance 0x1b21e6ef8 -[__NSCFConstantString objectForKeyedSubscript:]: unrecognized selector sent to instance-[__NSDictionaryI length]: unrecognized selector sent to instance 0x174264500

当那么些指标调用那么些不设有的法子的时候,替换来自身定义的二个主意,对它们做一下谬误包容,使利用不会崩溃。现截取部分代码达成,漫天源码会在随笔最终提供

@implementation NSString (NSRangeException)+ load{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @autoreleasepool { [objc_getClass("__NSCFConstantString") swizzleMethod:@selector(objectForKeyedSubscript:) swizzledSelector:@selector(replace_objectForKeyedSubscript:)]; } });}- replace_objectForKeyedSubscript:(NSString *)key { return nil;}@end

小结一下,变成NSInvalidArgumentException非凡大概有以下原因:

  • NSDictionary插入nil的对象。NSMutableDictionary也是同出一辙的道理。
  • NSJSONSerialization连串化的时候,传入data为nil。
  • an unrecognized selector 不能够辨认的方法

NSInvalidArgumentException的夭亡记录有149条(总崩溃记录304条),占49.01%,称霸Crash界,徘徊花排行第一。

iOS Crash 徘徊花排行

2.data parameter is nil

NSJSONSerialization种类化的时候,传入data为nil,变成的垮台,那几个难点比较好清除,在连串化的时候,统一参预推断,剖断data是还是不是nil就能够。

杀手 NO.2

SIGSEGV是当SEGV产生的时候,让代码终止的标志。当去做客还没被开辟的内部存款和储蓄器照旧已经被放走的内部存款和储蓄器时,就能够发生如此的要命。其余,在低内部存款和储蓄器的时候,也或许会发出这么的不行。

对于那样的十三分,大家得以行使三种艺术来缓和,一种艺术选用Xcode自带的内部存款和储蓄器分析工具,一种是选拔facebook提供的自动化学工业具来监测内部存款和储蓄器泄漏难题,如:FBRetainCycleDetector、FBAllocationTracker、FBMemoryProfiler

例子1:

dataOut = malloc(dataOutAvailable * sizeof;

那是采用Xcode自带的Leaks工具检查评定到的内存泄漏,通过代码大家来看那是叁个C语言使用malloc函数分配了一块内部存款和储蓄器地址,然而在不接受的时候却遗忘了自由其内部存款和储蓄器地址,那样就导致了内部存款和储蓄器泄漏,应该在其不选用的时候增多如下代码:

free;

其它,通过这几个例子大家也要极度注意,在运用C语言对象的时候,必须求记得在不应用的时候给自由掉,ARC并无法自由掉那块内部存款和储蓄器。

例子2:

Can't add self as subview crash 

招致那些崩溃的来由,一种原因是在push或pop三个视图的时候,并且安装了animated:YES,借使这时候卡通还未马到成功,当时,你在去push或pop其余二个视图的时候,就能够促成该特别。 也是有此外原因能够引致那么些崩溃,比如:

[self.view addSubview:self.view];

复现这些场所,作者写了五个底下的代码测量检验,如下:

- btnAction:sender { UIViewController *test01 = [[UIViewController alloc] init]; [self.navigationController pushViewController:test01 animated:YES]; [self.navigationController pushViewController:test01 animated:YES];}

化解该极其最简便的艺术是把animated设置为NO,可是非常不和睦,把系统自带的卡通片效果给去掉了。其它一种协调的方法正是通过runtime来拓宽贯彻了,通过平安的办法,确定保障当有调节器正在进展入栈或出栈时,未有此外入栈或出栈操作。实际源码会在作品最终提供。

SIGSEGV的咽气记录有57条(总共304条崩溃记录State of Qatar,占18.60%。在Crash界排行第二。

杀手 NO.1

NSInvalidArgumentException 异常

现身这些crash的因由有无数,选拔了崩溃次数非常多的crash。

crash 日志1-1

-[__NSPlaceholderDictionary initWithObjects:forKeys:count:]:
 attempt to insert nil object from objects[3]

crash日志获得了,怎么复现该地方吧?大家看出initWithObjects:forKeys:count:,猜度一下应当是NSDictionary初步化时的主题材料,在看前面包车型客车提示attempt to insert nil object,那时候就足以做三个推测,应该是NSDictionary开始化时插入nil对象变成的特别。下边大家写一段代码来验证一下:

NSString *password = nil;
NSDictionary *dict = @{
                       @"userName": @"bruce",
                       @"password": password
                       };
NSLog(@"dict is : %@", dict);

运营过后,崩溃音讯如下:

2017-01-23 23:08:15.056 CrashDemo[8592:599699] *** Terminating app due 
to uncaught exception 'NSInvalidArgumentException', reason: '***
 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert
 nil object from objects[1]'

地点的咽气消息认证了我们的估计。从崩溃日志记录中,查询到该难点的崩溃记录有33条(总崩溃记录304条),占10.85%,崩溃率比较高。为何汇合世这种光景呢?如何扼杀那样的crash呢?

崩溃率高的缘故是因为本人的框架中动用了去model化的宏图观念,不会把后台再次来到的数据转变来model,而是通过叁个reformer机制调换来NSDictionary格局,提供给目的对象使用,在转变到NSDictionary的进程中,后台重回的数码不时大概为空,就可以招致插入nil对象,进而招致crash。

3.unrecognized selector sent to instance 0x15d23910

变成这条崩溃的因由,想必我们都相比较了解了,正是八个类调用了贰个子虚乌有的艺术,变成的崩溃。消除那样的难点,能够在写贰个方法的时候,决断一下其类的体系,不相符项指标不让其调用

杀手 NO.3

产生那些特别,便是越界万分了,在iOS中大家平常蒙受的越界十分常有二种,一种是数组越界,一种字符串截取越界,大家由此crash日志来具体深入分析一下。

** crash 日志3-1 **

-[__NSArrayM objectAtIndex:]: index 1 beyond bounds for empty array-[__NSCFConstantString substringToIndex:]: Index 10 out of bounds; string length 0

通过日记能够很显明的理解难题,正是越界形成的,复现该现象也比较简单,在这里就略过了。怎么解决呢?

方案一:在对数组取数据的时候,要认清一下数组的尺寸超越取的index,这些要在平常写代码的时候给专门的学问起来。相像在对字符串举行截取的时候,也亟需做近似的剖断。但具体的景观是,有的时候大家会忘了写这么的逻辑判断,就能够有秘密的崩溃难题。咋做一下联结的论断呢?即使开辟人士忘了写那样的逻辑决断也不会以致崩溃,从框架层面来杜绝那类的崩溃,方案二交由了答案。

方案二:利用runtime的Swizzle Method性子,能够兑现从框架层面杜绝那类的崩溃难点,那样做的功利有两点:

  1. 开辟职员忘了写决断越界的逻辑,也不会导致app的垮台,对开垦职员来讲是晶莹剔透的。
  2. 没有必要改革现存的代码,对现成代码的侵入性降到低于,不要求加上海南大学学量重复的逻辑判别代码。

整套源码会在篇章最终提供,现截取部分代码完结:

@implementation NSArray (NSRangeException)+ load{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @autoreleasepool { [objc_getClass("__NSArray0") swizzleMethod:@selector(objectAtIndex:) swizzledSelector:@selector(emptyObjectIndex:)]; [objc_getClass("__NSArrayI") swizzleMethod:@selector(objectAtIndex:) swizzledSelector:@selector(arrObjectIndex:)]; [objc_getClass("__NSArrayM") swizzleMethod:@selector(objectAtIndex:) swizzledSelector:@selector(mutableObjectIndex:)]; [objc_getClass("__NSArrayM") swizzleMethod:@selector(insertObject:atIndex:) swizzledSelector:@selector(mutableInsertObject:atIndex:)]; } });}- emptyObjectIndex:(NSInteger)index{ return nil;}- arrObjectIndex:(NSInteger)index{ if (index >= self.count || index < 0) { return nil; } return [self arrObjectIndex:index];}- mutableObjectIndex:(NSInteger)index{ if (index >= self.count || index < 0) { return nil; } return [self mutableObjectIndex:index];}- mutableInsertObject:object atIndex:(NSUInteger)index{ if  { [self mutableInsertObject:object atIndex:index]; }}@end

越界的倒台记录有46条(总共崩溃记录是304条),占15.13%,在crash界徘徊花排名第三。

有3种方案能够缓和该难点,如下:

方案一:后台在回到数据的时候举行校验,对空值进行拍卖。可是在类型中某些空值是有独特的用场,此种方案不可行。

方案二:在调换到NSDictionary的时候,对后台再次回到的多寡进行校验,把空值转变来NSNull对象。方案可行,不过急需对现成代码做大的退换,每一次改动的时候都亟待开展校验,太难为。业务飞快发展时期,那样做基金太高。

方案三:有未有一种无须变动现成代码又能消除该难点吗?答案是一些,能够行使Objective-C的runtime来杀绝该难点。

NSDictionary插入nil对象会招致崩溃,可是插入NSNull对象是不会招致崩溃的,只要接纳runtime的Swizzle Method把nil对象给调换到NSNull对象就足以把该难题给消亡了。创建三个NSDictionary的项目,利用runtime的Swizzle Method来替换系统的点子。源码达成能够参照Glow团队卷入的NSDictionary+NilSafe(Github上可下载到State of Qatar, 全体源码会在小说最终提供,现截取在那之中的一部分代码如下:

- (void)gl_setObject:(id)anObject forKey:(id<NSCopying>)aKey {
    if (!aKey) {
        return;
    }
    if (!anObject) {
        anObject = [NSNull null];
    }
    [self gl_setObject:anObject forKey:aKey];
}

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = NSClassFromString(@"__NSDictionaryM");
        [class gl_swizzleMethod:@selector(setObject:forKey:) withMethod:@selector(gl_setObject:forKey:)];
        [class gl_swizzleMethod:@selector(setObject:forKeyedSubscript:) withMethod:@selector(gl_setObject:forKeyedSubscript:)];
    });
}

4.SIGSEGV 异常

当去拜见还没被开辟的内部存款和储蓄器照旧已经被释放的内部存款和储蓄器时,就能够发生这么的要命。其它,在低内部存款和储蓄器的时候,也可能会生出那样的不行,通常开采中用到C语言呢的时候可比便于并发这种混淆黑白,因为ARC并不会对C语言举办内存管理,所以用C语言创设的目的自然要手动Free

上一篇:没有了
下一篇:没有了
友情链接: 网站地图
Copyright © 2015-2019 http://www.tk-web.com. bb电子糖果派对有限公司 版权所有