假设我有三个相同大小的数组。我必须对所有物体做点什么。如果我使用标准C数组,我会写类似
for (i = 0; i < size; i++) {
doSomething(array1[i]); // or [[array1 objectAtIndex:i] doSomething];
doSomethingElse(array2[i]); // or [[array2 objectAtIndex:i] doSomethingElse];
doSomethingReallySpecial(array3[i]); // or [[array3 objectAtIndex:i] doSomethingReallySpecial];
}
使用Objective C,我们有更多方法在NSArray中循环遍历对象:快速枚举,基于块的枚举和使用枚举器。我应该使用哪一个?为什么?有什么区别?
修改
实际上这个问题可能是这样形成的:如果需要使用数组项的索引,应该使用哪个枚举?
答案 0 :(得分:4)
基于NSEnumerator的方法曾经是唯一受支持的枚举方法。我想不出它有什么好处 - 它更慢,更笨拙,并且在很大程度上被其他方法所取代。
使用块可以提供很大的灵活性。方法可以接受块作为参数,并使用它来枚举几个不同的集合:
- (void) doSomethingToFruits:(void(^)(id,NSUInteger,BOOL*))block
{
[apples enumerateObjectsUsingBlock:block];
[bananas enumerateObjectsUsingBlock:block];
[kiwis enumerateObjectsUsingBlock:block];
}
您还可以使用enumerateObjectsUsingBlock:options:
中的options参数同时枚举内容,。
我喜欢快速枚举的东西是NSFastEnumeration协议允许我添加一个接受数组或集合(或哈希表或其他)但仍然对参数进行静态类型检查的方法:
- (void) addObjectsFromCollection:(id<NSFastEnumeration>)coll
{
for (id obj in coll) [self addObject:obj];
}
否则,两者的语法似乎在不同的上下文中更合适。我发现如果一个方法的主体是枚举一个集合,那么如果我使用快速枚举就会更清楚,而如果我只是想在一个更大的方法中间对所有内容执行一个或两个动作,那么块更简洁,但我想这部分是个人偏好。
<强>附录:强>
如果要跟踪索引,则block选项接受索引作为参数。
答案 1 :(得分:0)
您应该使用最明确地表达代码意图的代码读者。除非您已将此循环识别为显着的性能瓶颈,否则维护代码的能力就更为重要。
也就是说,单独的快速枚举(即for(id i in array)
)不提供索引。如果您不想使用C风格的循环,-[NSArray enumerateObjectsUsingBlock:]
提供当前项和索引,并可用于压缩多个数组。我怀疑,对于多个阵列,C风格的方法通常在性能上实际上是等效的 - 也许读者可能更清楚,但你应该对其进行分析以确定。
你正在寻找的是函数式编程中常见的习惯用法,当然可以使用块在GCD之上实现,但我不知道任何实现。