48、多用块枚举,少用for循环
1、for循环
// 遍历NSArray
for (int i = 0; i < anArray.count; i++) {
id object = anArray[i];
}
// 遍历NSDictionary
NSArray *keys = [aDic allKeys];
for (int i = 0; i < keys.count; i++) {
id key = keys[i];
id value = aDic[key];
}
// 遍历NSSet
NSArray *objects = [aSet allObjects];
for (int i = 0; i < objects.count; i++) {
id object = objects[i];
} 创建附加数组会有额外开销,而且还会多创建一组对象,它会保留collection中的所有元素对象。释放时这些附加对象也要释放,这样就调用了一些本来不需要执行的方法。其他各种遍历方式都无须创建这种中介数组。
2、使用OC1.0的NSEnumerator来遍历
NSEnumerator是一个抽象基类,其中自定义了两个方法,供子类实现:
- (NSArray *)allObjects;
- (id)nextObjects; // 返回枚举里的下一个对象 Foundation框架中内建的collection类都实现了这种遍历方式:`
// 遍历NSArray
NSEunmerator *enumerator = [anArray objectEnumerator]; // reverseObjectEnumerator 方向遍历
id object;
while ((object == [enumerator nextObject]) != nil) {/*...*/}
// 遍历NSDictionary
NSEnumerator *enumerator = [aDic keyEnumerator];
id key;
while ((key = [enumerator nextObject]) != nil) {
id value = aDic[key];
}
// 遍历NSSet
NSEunmerator *enumerator = [aSet objectEnumerator];
id object;
while ((object == [enumerator nextObject]) != nil) {/*...*/}3、快速遍历
OC2.0引入了快速遍历,为for循环开设了in关键字。从而大幅简化了遍历collectin所需的语法:
// 遍历NSArray
for (id object in anArray) {/*...*/}
// 遍历NSDictionary
for (id key in anDic) {
id value = aDic[key];
}
// 遍历NSSet
for (id object in aSet) {/*...*/} 支持快速遍历,遵从`NSFastEnumeration`协议就好,只有一个协议方法:- (NSinterger)countBeyEnumeratingWithState:(NSFastEnumerationState *)state
objects:(id *)stackbuffer
count:(NSUInteger)length; NSEnumerator对象也实现了NSFastEnumeration协议,所以能用来执行方向遍历:
for (id object in [anArray reverseObjectEnumerator]) {/*...*/}4、基于块的遍历方式(遍历时可以获取更堵信息)
NSArray *anArray = [NSArray array];
[anArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (shouldStop) {
*stop = YES; // 优雅的终止遍历(其他的遍历可以用break终止)
}
}];
NSDictionary *aDic = [NSDictionary dictionary];
[aDic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
if (shouldStop) {
*stop = YES;
}
}];
NSSet *aSet = [NSSet set];
// 可以修改方法签名,以免进行类型转换操作
[aSet enumerateObjectsUsingBlock:^(NSString *obj, BOOL * _Nonnull stop) {
if (shouldStop) {
*stop = YES;
}
}]; 可以利用另一个版本指向方向遍历、并发遍历:
// NSEnumerationConcurrent 并发的方式遍历
// NSEnumerationReverse 方向遍历
[anArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
}];要点:
遍历
collection有四种方式。最基本的办法是for循环,其次是NSEnumerator遍历法及快速遍历法。最新、最先进的方式则是“块枚举法”“块枚举法”本身就能通过GCD来并发执行遍历操作,无须另行编写代码。而采用其他遍历方式则无法轻易实现这一点
若提前知道待比啊你了的
collection含有何种对象,则应该修改块签名,指出对象的具体类型
Last updated
Was this helpful?