我一遍又一遍地看到这一点,为什么在循环中使用快速枚举比使用nextObject:的NSEnumerator更快。
发布于 2011-03-02 12:18:21
NSEnumerator是枚举集合的旧方法。它涉及到创建一个表示枚举的对象,然后在每次迭代中调用该对象上的方法。虽然多年来这是完美的服务,但它的效率并不是非常高,因为它在循环的每次迭代中至少涉及一次消息发送。NSFastEnumeration是更现代的方法,它利用本机语言支持来提供更有效的枚举。它在幕后的工作方式是创建一个表示当前枚举状态的结构,并在集合上重复调用-countByEnumeratingWithState:objects:count:。该方法在objects出参数中返回一个对象的C数组,在count出参数中返回一个计数器。这允许调用者随后迭代C数组。本质上,这意味着每个对象块都有一个消息调用,根据集合的不同,这可能与获取所有对象的单个消息调用的效率一样高。
如果你有一些看起来像这样的代码
for (id obj in myArray) {
[obj doSomething];
}这将由编译器翻译成大致等同于
NSFastEnumerationState __enumState = {0};
id __objects[MAX_STACKBUFF_SIZE];
NSUInteger __count;
while ((__count = [myArray countByEnumeratingWithState:&__enumState objects:__objects count:MAX_STACKBUFF_SIZE]) > 0) {
for (NSUInteger i = 0; i < __count; i++) {
id obj = __objects[i];
[obj doSomething];
}
}实际使用的变量是隐藏的,对象缓冲区的最大大小也取决于实现,但基本思想是存在的。它将obj-c集合上的迭代转换为C数组上的迭代。
发布于 2011-03-02 12:30:03
它与Apple的实现不同,但对理解它很有帮助。
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
objects: (id*)stackbuf
count: (NSUInteger)len
{
IMP nextObject = [self methodForSelector: @selector(nextObject)];
int i;
state->itemsPtr = stackbuf;
state->mutationsPtr = (unsigned long*)self;
for (i = 0; i < len; i++)
{
id next = nextObject(self, @selector(nextObject));
if (nil == next)
{
return i;
}
*(stackbuf+i) = next;
}
return len;
}发布于 2011-03-02 12:16:58
NSArray *array = something;数组={ {1,2},{2,3},{3,4} }
这意味着array是一个数组的数组。那么如何访问所有数组和它们的值呢?我们可以像这样使用for循环
for (int i = 0; i < array.count; i++)
{
NSArray x = [array objectAtIndex:i];
}或者快速枚举的工作方式如下所示
for(NSArray array2 in array)
{
// do what ever you want with this new array2.
}这是一个示例。
PS。我忘记了数组在控制台中的样子。
https://stackoverflow.com/questions/5163169
复制相似问题