runtime 网上一大堆,这里不介绍了,利用runtime特性,当数组和字典调用指定的存取方法时,通过runtime填加中间方法来判断参数的合法性来避免造成crash。
写之前先简介一下两个概念:
1.指定初始化(Designated Initializer)The initializer of a class that takes the full complement of initialization parameters is usually the designated initializer. The designated initializer of a subclass must invoke the designated initializer of its superclass by sending a message to super.。
2.间接初始化(Secondary Initializer)The convenience (or secondary) initializers—which can include init—do not call super. Instead they call (through a message to self) the initializer in the series with the next most parameters, supplying a default value for the parameter not passed into it.
大意是指定初始化方法通常会有很多参数,为了方便有了间接初始化方法,只提供需要的参数,间接初始化方法最后都会通过指定初始化方法来初始化对象。如下图
图1直奔主题
NSArray
大家都知道数组和字典都属于类簇是由工厂方法抽象出来的类,其中NSArray 大概有以下几类具体类:
__NSPlaceholderArray ,__NSArray0,__NSSingleObjectArrayI,__NSArrayI 如下图
图2其中__NSPlaceholderArray是只alloc而没有初始化,而其它三个都是不同的初始化而来
1.存nil造成crash
不可变数组因不可变所以只有通过指定初始化来赋值,如图
图3所以直接操作此方法即可
图4 图5这里用__NSPlaceholderArray是因为对象先alloc再调用初始化,而alloc会生成__NSPlaceholderArray。
2.越界
上图
图6 图7 图8 图9发现都会调用objectAtIndex:方法 只是调用类是NSArray的具体类,所以这里分别对具体类操作objectAtIndex:即可:
方法:
图10实现:
图11NSMutableArray
即__NSArrayM大概只操作以下方法即可
图12具体实现就不写了,有兴趣的去下载Demo。
NSDictionary
和NSArray一样,只操作指定初始化方法即可,如图
图13还有一个需要注意的是NSDictionary可以通过-setValue:forKey:方法来修改value,此方法的value可以为nil,但是key不可以为nil 并且key不能是NSDictionary原有key以外的值。此方法是NSObject的方法,这里就不修改了,如果想修改应放到NSObject类别中,这些子类自然可以调用。
图14NSMutableDictionary
即__NSDictionaryM也只操作增删改查。
增:
图15还有一点需要了解一下当调用- setObject:forKeyedSubscript:和-setValue: forKeyPath:方法时 会调用 如下方法
图16当值参数为nil时则会调用-removeObjectForkey:方法,当key也是nil时则crash,这里remove的修改会放在删的模块里。
删:
图17改和增的方法一样,查key可以为nil。
小记到此为止了,当然 还有NSSet等类簇也同字典数组一样,只是不常用,有时间整理还不如用的时候小心一些呢,如有不足,请大家指出,共同学习。
网友评论