如何在类之间共享常量(枚举)?

时间:2012-02-29 19:18:21

标签: objective-c ios enums

我有一些UIPopoverViewControllers发送消息来委派UIViewControllers来传递UI事件。我没有为每个事件编写单独的方法,而是在委托中有一个方法,它有一个switch语句,用于确定如何根据传递的常量处理事件(例如下面的例子)。

这可能是糟糕的设计,但这是我想出来的。我已经看到this关于枚举或静态类的问题但却不理解答案。

所以..我正在做什么 BAD 并且有一种方法可以在一个地方定义枚举,这样我就不必维护多个可以轻松搞定的代码同步?

编辑好的,多挖掘一下(here + here)我发现我可能走在正确的轨道上。所以我想我需要知道iOS中的implementation文件的位置和位置。

enum {
kSetPlaybackType = 0,
kSetAllNotesOn,
kSetAllNotesOff,
kSetVelocity,
kSetDuration
};

- (void)barPropertyAction:(int)action withParam:(NSNumber *)param
{
switch (action) {
    case kSetPlaybackType:
        playbackType = [param intValue];
        if (playbackType == kPalindrome){
            palindromeDirection = kPalindromeUp;
        }
        break;

    case kSetAllNotesOn:
        for (BarNote* note in self.barNoteArray) {
            note.noteOn = YES;
        }
        [self.bar updateWindows];
        break;

    case kSetAllNotesOff:
        for (BarNote* note in self.barNoteArray) {
            note.noteOn = NO;
        }
        [self.bar updateWindows];
        break;

    case kSetVelocity:
         for (BarNote* note in self.barNoteArray) {
            note.velocity = [param intValue];
        }
        break;

    case kSetDuration:
        for (BarNote* note in self.barNoteArray) {
            note.duration = [param floatValue];
        }
        break;

    default:
        break;
}
}

1 个答案:

答案 0 :(得分:15)

我不会说你的做法是那么糟糕,但对于“神”方法的起始胚胎确实有一点点感觉 - 这是一种试图做所有事情的方法。但是,对于代码中的选择数量,我会说完全没问题。

但是分享枚举很简单。只需将它们放在自己的.h文件中,然后将其导入需要的地方。您可以将.h文件作为“C& C ++”部分下的文件类型之一。

您引用的问题是基于C#,他们在该语言中做的一件事是设计相当于.h文件,并使用“using”语句来定位正确的符号。在Objective-C中(如在C和C ++中),你必须做更多的手工工作来实现同样的目标。

顺便说一下,我会把枚举更多地打扮成:

typedef enum {
  kSetPlaybackType = 0,
  kSetAllNotesOn,
  kSetAllNotesOff,
  kSetVelocity,
  kSetDuration
} SetEnumType;

通过在typedef中声明枚举,您可以声明该类型的变量。即代替:

int varName = kSetAllNotesOn;

你可以说:

SetEnumType varName = kSetAllNotesOn;

这为XCode提供了额外的提示,当您向自己提供自动填充选项时,它可以在语义上更好地作为一个人阅读,因为您知道varName旨在保存枚举,而不仅仅是任何旧数字。

缺点是您可能需要在枚举类型和int类型之间显式地转换varNum,具体取决于您正在做什么。

但是我不确定您是否可以将方法签名声明为

- (void)barPropertyAction:(SetEnumType)action withParam:(NSNumber *)param

我猜你应该能够(因为我认为枚举是由int支持的)。但如果你不能,那么你最好做

- (void)barPropertyAction:(int)action withParam:(NSNumber *)param
{
switch ((SetEnumType)action) {
    case kSetPlaybackType:
        playbackType = [param intValue];