【问题标题】:Iteration over enum in Objective C?在Objective C中迭代枚举?
【发布时间】:2011-08-02 09:47:26
【问题描述】:

我有

enum Colour {
    white,
    pink,
    yellow,
    blue
} Colour;

我想做这样的事情:

for (int colour in Colour){
    // Do something here.
}

我可以这样做吗?如果可以,怎么做?感谢您的帮助!

【问题讨论】:

标签: objective-c


【解决方案1】:

虽然问题已经回答了,但这是我的两分钱:

enum Colour {
    white = 0,
    pink,
    yellow,
    blue,

    colorsCount // since we count from 0, this number will be blue+1 and will be actual 'colors count'
} Colour;

for (int i = 0; i < colorsCount; ++i)
  someFunc((Colour)i);

我想这还不错,并且非常接近您想要的快速枚举。

【讨论】:

  • 如此简单却又如此出色;)
  • 聪明的主意,但难闻的气味。将功能潜入像枚举这样的识别机制会破坏其意图和凝聚力。
  • dooleyo,这种“枚举”对于 C/C++ 编码人员来说非常典型。当然,它只适用于特定的数字枚举。
  • 这个想法的唯一问题是,当您对其执行 switch 语句时,您必须开始始终满足这个额外的枚举
  • 如果我希望粉色为 5,那么黄色会自动为 6,对吗?那么这4个漏案(1,2,3,4)应该如何处理呢?我也可以将粉色大小写值更改为 60、600 等。
【解决方案2】:

枚举来自 C,而快速枚举是 Objective-C 2.0 的补充。它们不能一起工作。

Type existingItem;
for ( existingItem in expression ) { statements }

表达式必须符合 NSFastEnumeration 协议并且是一个对象!枚举的“元素”不是对象。

查看此链接了解更多信息Apple's Fast Enumeration Documents

查看此示例以了解枚举的工作速度:

NSArray *array = [NSArray arrayWithObjects:
        @"One", @"Two", @"Three", @"Four", nil];

for (NSString *element in array) {
    NSLog(@"element: %@", element);
}

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
    @"quattuor", @"four", @"quinque", @"five", @"sex", @"six", nil];

NSString *key;
for (key in dictionary) {
    NSLog(@"English: %@, Latin: %@", key, [dictionary objectForKey:key]);
}

【讨论】:

  • 我没有,但它显然只会让我在 5 分钟后这样做; )
  • 在这个答案中我知道哪个值是我想要的索引值我怎么能找到请帮助谢谢
【解决方案3】:

枚举中的“Count”元素很好,但它会在switch 语句中为您提供“并非所有开关案例都已处理”,除非您在其中处理此“count”元素。也许更好的方法是对第一个和最后一个元素使用别名:

enum Colour {
    firstColour = 0,

    white = firstColour,
    pink,
    yellow,
    blue,

    lastColour = blue
} Colour;

for (int i = firstColour; i <= lastColour; ++i) {

}

【讨论】:

  • 蓝色会被触发两次
  • @OlSen nope, as blue == lastColour
【解决方案4】:

我来这篇文章也是为了回答这个问题。戈布拉的回答很棒。但是我的项目数量可能会波动,并且与存储的值相关,因此为了更加安全,“colorsCount”计数是或从来不是一个有效值,我最终实现了以下内容并希望添加到讨论中:

MYColor.h

typedef NS_ENUM( NSInteger, MYColorType )
{
    MYColorType0 = 0,
    MYColorType1,
    MYColorType2,
    MYColorType3
};

static inline MYColorType MYColorTypeFirst() { return MYColorType0; }
static inline MYColorType MYColorTypeLast() { return MYColorType3; }

ViewController.m

for ( int i = MYColorTypeFirst(); i <= MYColorTypeLast(); i++ )
{
    MYColor * color = [[MYColor alloc] initWithType:i];
    ...
}

值得注意的添加是在 for() 迭代中使用的 MYColorTypeFirst() 和 MYColorTypeLast() 的定义,它们放置在枚举定义附近以实现可维护性。

【讨论】:

    【解决方案5】:

    对于我不是枚举作者的情况,我会这样做。我认为这是非常安全的,因为它不关心枚举类型的实际实现方式。

        UISwipeGestureRecognizerDirection allDirections[] = {
            UISwipeGestureRecognizerDirectionDown,
            UISwipeGestureRecognizerDirectionLeft,
            UISwipeGestureRecognizerDirectionRight,
            UISwipeGestureRecognizerDirectionUp
        };
    
        for (int i = 0; i < sizeof(allDirections)/sizeof(allDirections[0]); ++i) {
            UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipe:)];
            swipeGesture.direction = allDirections[i];
            [self addGestureRecognizer:swipeGesture];
        }
    

    【讨论】:

    • 完成后不需要释放该数组吗?
    • 那个数组在栈内存中,当你离开作用域时它应该被自动清除。
    • 如果我将其创建为静态并从函数中返回呢?
    • 如果它是静态的,它将永远存在。你可以发布一些代码,你想要做什么?
    【解决方案6】:

    这是使用预处理器避免弄脏编译代码的完美用例


    在您的 .h 中:

    typedef NS_ENUM(NSUInteger, EnumValue)
    {
        EnumValueOne,
        EnumValueTwo,
        EnumValueThree,
        EnumValueFour
    #define EnumValueLast EnumValueFour
    };
    

    应用中的其他地方:

    for (EnumValue value = 0; value <= EnumValueLast; value++) {
        //do stuff
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-26
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      相关资源
      最近更新 更多