美文网首页iOS开发者iOS开发·数据篇iOS开发技术
教你自己动手一步步实现iOS 数组字典操作safe拓展

教你自己动手一步步实现iOS 数组字典操作safe拓展

作者: StrivEver | 来源:发表于2016-08-05 14:59 被阅读1422次

iOS开发中需要大量对dictionary和array进行操作,因此我们需要一种更加安全可靠的操作方法来避免不必要的crash。当然可以通过自定义dictionary 和array重载增删改查的方法来避免crash,但是由于许多工程基本成型以后,如此操作的话工作量,改动等都会很大。此时我们可以利用OC语言动态特性对数组和字典的增删改查方法进行Method Swizzling(不懂得自行百度吧) ,替换成我们经过安全操作的方法,从而进行安全操作。当然有好多大神已经实现过了,但是毕竟会用并不代表是自己的。好了废话不多说吧,下面我们就开始自己动手一步步实现我们自己的safe类吧。

一. 首先第一步我们需要知道字典和素组进行操作(也支持字面量操作)崩溃的原因有哪些:

  1. 不可变数组NSArray 常用的方法有 objectAtIndex objectAtIndexedSubscript arrayByAddingObject arrayWithObject

    主要的crash reason是数组越界,运行一下代码

    代码1代码1
    程序崩溃 看下日志reason: '*** -[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2]

    运行下面代码 数组中追加了一个nil值

    代码2代码2

    程序崩溃日志reason: '*** -[NSArray arrayByAddingObject:]: object cannot be nil'

    运行代码NSArray * testArray = [NSArray arrayWithObject:nil];崩溃日志reason: '*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]

  2. 可变数组常用方法 增删改查等 主要有
    1.[__NSPlaceholderArray initWithObjects:count:] 2.[__NSArrayM insertObject:atIndex:] 3.[__NSArrayM objectAtIndex:] 4.[__NSArrayM removeObjectAtIndex:] 5.[__NSArrayM replaceObjectAtIndex:withObject:] 6.[NSMutableArray replaceObjectsInRange:withObjectsFromArray:]

  3. 不可变字典 初始化有空值 [__NSPlaceholderDictionary initWithObjects:forKeys:count:]

  4. 可变字典常用方法setObject: forKey: removeObjectsForKeys: removeObjectForKey: 进行操作是key value 不能为nil

二. 第二步我们利用runtime在实现load方法( + load 方法,那么当类被加载时它会自动被调用)时将这些方法进行hook,注意方法进行Swizzling时候程序生命周期内只需要执行一次:

对NSArray举例实现一下
1\.新建NSArray的categary NSArray+Safe
当数组越界时 crash reason[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2] 我们需要使用函数method_exchangeImplementations(method1,method2)交换两个方法的实现指针 因为交换指针需要多次使用,我们对此方法进行封装
如下图:

代码3代码3

实现一下load函数
如下图

代码4代码4
实现我们自定义的方法
如下图
代码5代码5
ok,数组越界已经解决了!可以试一下啦!

其他的都是大同小异,下面是我的github地址,将库拖到工程里边就可以啦!
博客地址

欢迎加入iOS开发群【557851038】

相关文章

网友评论

  • 飞翔de小苹果:这个方法有内存溢出,什么情况?
    - (instancetype)initWithObjects_st:(id *)objects count:(NSUInteger)count {
    NSUInteger newCount = 0;
    for (NSUInteger i = 0; i < count; i++) {
    if (!objects[i]) {
    break;
    }
    newCount++;
    }
    self = [self initWithObjects_st:objects count:newCount]; //具体是这里
    return self;
    }
    ___1o_8o:objects后面的东西
  • zjw7sky:swizz数组,字典,你不怕出问题。。
  • Joy___:强
    Joy___:@StrivEver :smiley_cat::innocent:
    StrivEver:@Martin_Joy :joy::joy:
  • SugarW:谢谢楼主,另外,最后两张图一样的?
    StrivEver:@SugarW 好像放错了。。。
  • 红烧大鸡腿:SystemClass是否可以为NSArray?
    StrivEver:@HCX_IOS 运行时真正的类名是__NSArrayI
    红烧大鸡腿:@StrivEver 这个是为什么不可以?在网上找了半天并没有找到满意的答案😊😊😊
    StrivEver:@HCX_IOS 不行的,崩溃日志里边的类

本文标题:教你自己动手一步步实现iOS 数组字典操作safe拓展

本文链接:https://www.haomeiwen.com/subject/ycwhsttx.html