微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何迭代 NSArray?

如何解决如何迭代 NSArray?

10.5+/iOS 的普遍首选代码

for (id object in array) {
    // do something with object
}

此构造用于枚举符合NSFastEnumeration协议的集合中的对象。这种方法具有速度优势,因为它将指向多个对象(通过单个方法调用获得)的指针存储在缓冲区中,并通过使用指针算法在缓冲区中前进来迭代它们。这比每次通过循环调用 快得多。-objectAtIndex:

还值得注意的是,虽然您在技术上 可以 使用 for-in 循环来单步执行NSEnumerator,但我发现这几乎抵消了快速枚举的所有速度优势。原因是NSEnumerator实现-countByEnumeratingWithState:objects:count:在每次调用时只在缓冲区中放置一个对象。

我在radar://6296108(NSEnumerators 的快速枚举缓慢)中报告了这一点,但它被返回为 Not To Be Fixed。原因是快速枚举会预取一组对象,如果您只想枚举到枚举器中的给定点(例如,直到找到特定对象或满足条件)并在中断后使用相同的枚举器在循环中,通常会跳过几个对象。

如果您正在为 OS X 10.6 / iOS 4.0 及更高版本进行编码,您还可以选择使用基于块的 API 来枚举数组和其他集合:

[array enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop) {
    // do something with object
}];

您还可以使用-enumerateObjectsWithOptions:usingBlock:和传递NSEnumerationConcurrent和/或NSEnumerationReverse作为选项参数。


10.4 或更早版本

10.5 之前的标准习惯用法是使用一个NSEnumerator一个 while 循环,如下所示:

NSEnumerator *e = [array objectEnumerator];
id object;
while (object = [e nextObject]) {
  // do something with object
}

我建议保持简单。将自己绑定到数组类型是不灵活的,并且据称使用的速度增加-objectAtIndex:对于 10.5+ 上的快速枚举的改进是微不足道的。(快速枚举实际上在底层数据结构上使用了指针运算,并消除了大部分方法调用开销。)过早的优化从来都不是一个好主意——它会导致解决问题的代码更混乱,而这并不是你的瓶颈。

使用 时 ,您很容易更改为另一个可枚举集合(如 an NSSet、 an 中的键NSDictionary等),甚至切换到 向后枚举数组,所有这些都无需更改其他代码。如果迭代代码一个方法中,您甚至可以传入任何方法NSEnumerator代码甚至不必关心它正在迭代什么。 此外,NSEnumerator只要有更多对象,(至少由 Apple 代码提供的那些)集合就会保留它正在枚举的集合,因此您不必担心自动释放的对象将存在多长时间。

也许一个(或快速枚举)保护您免受最大的事情是在您枚举它时在 您不知情的情况NSEnumerator下在您下面更改一个可变集合(数组或其他) 。如果您按索引访问对象,您可能会遇到奇怪的异常或一个错误(通常在问题发生很久之后),这对于调试来说可能是可怕的。使用标准惯用语之一进行枚举具有“快速失败”行为,因此当您在发生突变后尝试访问下一个对象时,问题(由不正确的代码引起)将立即显现出来。随着程序变得越来越复杂和多线程,甚至依赖于第三方代码可能修改的东西,脆弱的枚举代码变得越来越成问题。封装和抽象 FTW!:-) __


解决方法

我正在寻找迭代 NSArray 的标准习惯用法。我的代码需要适合 OS X 10.4+。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。