首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Objective-C中的快速枚举与NSEnumerator

Objective-C中的快速枚举与NSEnumerator
EN

Stack Overflow用户
提问于 2011-03-02 11:48:46
回答 3查看 4.5K关注 0票数 10

我一遍又一遍地看到这一点,为什么在循环中使用快速枚举比使用nextObject:NSEnumerator更快。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-03-02 12:18:21

NSEnumerator是枚举集合的旧方法。它涉及到创建一个表示枚举的对象,然后在每次迭代中调用该对象上的方法。虽然多年来这是完美的服务,但它的效率并不是非常高,因为它在循环的每次迭代中至少涉及一次消息发送。NSFastEnumeration是更现代的方法,它利用本机语言支持来提供更有效的枚举。它在幕后的工作方式是创建一个表示当前枚举状态的结构,并在集合上重复调用-countByEnumeratingWithState:objects:count:。该方法在objects出参数中返回一个对象的C数组,在count出参数中返回一个计数器。这允许调用者随后迭代C数组。本质上,这意味着每个对象块都有一个消息调用,根据集合的不同,这可能与获取所有对象的单个消息调用的效率一样高。

如果你有一些看起来像这样的代码

代码语言:javascript
复制
for (id obj in myArray) {
    [obj doSomething];
}

这将由编译器翻译成大致等同于

代码语言:javascript
复制
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数组上的迭代。

票数 29
EN

Stack Overflow用户

发布于 2011-03-02 12:30:03

  • GCC 8.9.4 Fast enumeration protocol
  • GNUstep libs/base/trunk/Source/NSEnumerator.m countByEnumeratingWithState:objects:count:

它与Apple的实现不同,但对理解它很有帮助。

代码语言:javascript
复制
- (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;
}
票数 2
EN

Stack Overflow用户

发布于 2011-03-02 12:16:58

代码语言:javascript
复制
NSArray *array = something;

数组={ {1,2},{2,3},{3,4} }

这意味着array是一个数组的数组。那么如何访问所有数组和它们的值呢?我们可以像这样使用for循环

代码语言:javascript
复制
for (int i = 0; i < array.count; i++)
{
    NSArray x = [array objectAtIndex:i];
}

或者快速枚举的工作方式如下所示

代码语言:javascript
复制
for(NSArray array2 in array)
{
   // do what ever you want with this new array2.
}

这是一个示例。

PS。我忘记了数组在控制台中的样子。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5163169

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档