接上篇《 iOS中的crash防护(一)unrecognized selector sent to instance》 我们攻克了找不到方法实现的crash,这一篇我这里主要分析一下在KVC常见的crash。以及防护措施。

[object setValue:nil forKey:key]

   value为nil。key不为nil的时候会调用-(void)setNilValueForKey:(NSString *)key这种方法,我这里对这种方法进行重写,代码例如以下:

-(void)setNilValueForKey:(NSString *)key{
NSString *crashMessages = [NSString stringWithFormat:@"JKCrashProtect:'NSInvalidArgumentException', reason: '[%@ %p setNilValueForKey]: could not set nil as the value for the key %@.'",NSStringFromClass([self class]),self,key];
[[JKCrashProtect new] JKCrashProtectCollectCrashMessages:crashMessages];
}

測试代码:

 NSObject *object = [NSObject new];
[object setValue:nil forKey:@"name"];

执行结果例如以下:

2017-05-04 19:14:14.073 JKCrashProtect_Example[28537:4028815] demo JKCrashProtect:'NSUnknownKeyException', reason: '[NSObject 0x600000003b30 setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key: name,value:(null)'

大家能够看到程序不再产生crash,并且将crash打印信息 出来方便我们定位crash。

非对象属性value为nil产生的crash

实例代码例如以下:

@interface Person : NSObject

@property (nonatomic,copy)NSString *name;
@property (nonatomic,assign)NSInteger age; @end

測试代码:

 Person *jack = [Person new];
[jack setValue:nil forKey:@"age"];

假设我们不进行crash防护的话,上面的这段測试代码就会产生crash,可是进行防护后。执行结果例如以下:

2017-05-04 21:19:52.496 JKCrashProtect_Example[29792:4065383] demo JKCrashProtect:'NSInvalidArgumentException', reason: '[Person 0x608000225560 setNilValueForKey]: could not set nil as the value for the key age.'

程序并没有crash,并且crash信息也被打印了出来,方便我们定位。

key不是object的属性产生的crash

  假设key不是object的属性的话,我们进行KVC赋值操作的话,也是会产生crash的。

測试代码例如以下:

 NSObject *object = [NSObject new];
[object setValue:@"abc" forKey:@"123"];

执行结果例如以下:

2017-05-04 21:26:21.357 JKCrashProtect_Example[29942:4071385] demo JKCrashProtect:'NSUnknownKeyException', reason: '[NSObject 0x600000203180 setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key: 123,value:abc'

程序相同没有崩溃。并且将crash打印信息了出来,方便我们定位。

[object setValue:value forKey:nil]产生的crash

   当key为nil的时候程序会产生crash。当然了这里能够通过method swizzle进行处理,可是这违背了,JKCrashProtect创建的初衷:仅仅在crash产生的时候,进行相关的处理,没有crash的时候。程序正常执行。尽可能少的产生性能损耗。这个在静态时,编译器会有警告,一般这个crash产生在动态传入key时未做非空处理,我这边临时没有好的解决方式。假设大家有的话,欢迎大家留言一块讨论哦。

[object setValue:value forKeyPath:keyPath];

   假设keyPath不对,这个时候程序也会产生crash,我这边进行crash防护后。測试代码例如以下:

@interface Country : NSObject
@property (nonatomic,copy)NSString *name;
@end @interface Person : NSObject @property (nonatomic,copy)NSString *name;
@property (nonatomic,assign)NSInteger age;
@property (nonatomic,strong)Country *country;
@end
Country *country = [Country new];
jack.country =country;
[jack setValue:@"111" forKeyPath:@"abc.name"];

这里keyPath我随便写了一个。执行结果例如以下:

2017-05-04 23:30:20.580 JKCrashProtect_Example[30774:4107964] demo JKCrashProtect:'Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[Person 0x6000004280c0 valueForUndefinedKey:]: this class is not key value coding-compliant for the key: abc

程序并没有crash。并且crash信息也被打印了出来,方便我们定位。

今天要说的就这些了。欢迎大家持续关注哦。

demo地址

cocoaPod:

pod "JKCrashProtect"

iOS中的crash防护(二)KVC造成的crash的更多相关文章

  1. 在iOS中使用ZBar扫描二维码

    最近在做的项目中需要用到二维码扫描功能,之前在Android中使用过ZXing识别二维码,ZXing也有对应的iOS版本,经过了解,ZBar也是一个常用的二维码识别软件,并分别提供了iOS和Andro ...

  2. Quartz 2D在ios中的使用简述二:创建画布

    在iOS中使用Quartz画图时,第一步就是要获取画布(图形上下文),然后再画布上做各种操作.先看下CoreGraphics.h这个头文件,就可以知道能够创建多少种上下文类型. #include &l ...

  3. iOS中Block介绍(二)内存管理与其他特性

    我们在前一章介绍了block的用法,而正确使用block必须要求正确理解block的内存管理问题.这一章,我们只陈述结果而不追寻原因,我们将在下一章深入其原因. 一.block放在哪里 我们针对不同情 ...

  4. iOS中的图像处理(二)——卷积运算

    关于图像处理中的卷积运算,这里有两份简明扼要的介绍:文一,文二. 其中,可能的一种卷积运算代码如下: - (UIImage*)applyConvolution:(NSArray*)kernel { C ...

  5. iOS中 基于LBXScan库二维码扫描 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博 首先声明这个二维码扫描是借助于zxing. 功能模块都完全封装好了,不过界面合你口味,直接使用就好,如果不合口味,后 ...

  6. 在iOS中使用ZBar扫描二维码和条形码

    最近做了个外包项目,里面用到了二维码扫描和微信支付!之前比较熟悉的是ZXing,但是在Xcode7.1里面发现竟然莫名的不支持,木有办法,从网上查了一下还有一种支持二维码扫描的东西,没错就是接下来我要 ...

  7. iOS中多线程知识总结(二)

    1.GCD GCD全称是Grand Central Dispatch,译为"强大的中枢管理器" 1)什么是任务?什么是队列? 任务和队列是GCD的核心. 任务: 执行什么操作 队列 ...

  8. ios中键盘处理(二)

    设置UIscrollview的背景代码 - (UIImage *) ImageWithColor: (UIColor *) color frame:(CGRect)aFrame { UIGraphic ...

  9. 玩转iOS开发:iOS中的GCD开发(三)

    上一章, 我们了解到了GCD里的一些队列和任务的知识, 也实践了一下, 同时我们也对主队列的一些小情况了解了一下, 比如上一章讲到的卡线程的问题, 如果没有看的朋友可以去看看玩转iOS开发:iOS中的 ...

随机推荐

  1. 0x5C 数位统计DP

    怎么说,数位DP还是我的噩梦啊,细节太恐怖了. 但是这章感觉又和之前的学的数位DP有差异?(应该是用DP预处理降低时间复杂度,好劲啊,不过以前都是记忆化搜索的应该不会差多少) poj3208 f[i] ...

  2. 转载【梦想天空(山边小溪)】Web 开发人员和设计师必读文章推荐【系列二十九】

    博客地址:http://www.cnblogs.com/lhb25/p/must-read-links-for-web-designers-and-developers-volume-29.html

  3. poj 1161 Floyd+枚举

    题意是: 给出n个点,围成m个区域.从区域到另一个区域间需穿过至少一条边(若两区域相邻)——边连接着两点. 给出这么一幅图,并给出一些点,问从这些点到同一个区域的穿过边数最小值. 解题思路如下: 将区 ...

  4. lua类实现

    _Account = {} --创建一张借记卡 function _Account:new( tb ) local _Tb = tb or {} setmetatable(_Tb, self) sel ...

  5. [hihocoder][Offer收割]编程练习赛43

    版本号排序 不知道什么傻逼原因,就是过不了 #pragma comment(linker, "/STACK:102400000,102400000") #include<st ...

  6. C#自定义控件实现控件随窗口大小改变

    1.新建用户控件,取名MyForm. 2.将默认的UserControl改成Form 3.在类中添加以下代码 private float X, Y; //获得控件的长度.宽度.位置.字体大小的数据 p ...

  7. root密码忘记怎么办?

    忘记root密码:按 e进入内核在按e,后面加1 .按b启动 进入命令行输入passwd,设置新的密码后exit退出即可

  8. matplotlib简介-高质量图形输出

    Matplotlib 是一个用来绘制二维图形的 Python 模块,它克隆了许多 Matlab 中的函数, 用以帮助 Python 用户轻松获得高质量(达到出版水平)的二维图形. 文章来源:http: ...

  9. 引用css样式的书写格式

    css的书写格式一共有三种 行内样式:意思是在行内中写样式 例如说<p style="color:red">用行内样式编写我的颜色</p> 只适用于< ...

  10. 使用meta实现页面的定时刷新或跳转

    <meta http-equiv="refresh" content="5"> 这个表示当前页面每5秒钟刷一下,刷一下~ <meta http ...