Почему я не могу использовать свою константу в операторе switch - case в Objective-C? [ошибка = выражение не целочисленное константное выражение]

поэтому у меня есть проблема с использованием постоянной переменной в следующем операторе switch в Objective-C.

Я константы.h следующим образом:

// Constants.h    
extern NSInteger const TXT_NAME;

и константы.м as:

// Constants.m
#import "Constants.h"

NSInteger const TXT_NAME        = 1;

затем в TabBasic.м Я пытаюсь использовать эту константу в операторе switch-case:

// TabBasic.m

#import "TabBasic.h"
#import "Constants.h"

... code ...

- (IBAction)saveValue:(id)sender {
    if ([sender isKindOfClass: [UITextField class]]) {
        UITextField *txtField = (UITextField *) sender;

        switch (txtField.tag) {
            case TXT_NAME:
                NSLog(@"Set property name to: %@", txtField.text); 
                break;
        }
    }
}

но, к сожалению, это дает мне следующие две ошибки в " case TXT_NAME:" строка:

  • выражение не является целочисленным постоянным выражением
  • метка случая не сводится к целочисленной константе

кто-нибудь знает, что я делаю неправильно? Переменная " tag " UITextField возвращает NSInteger, поэтому я не вижу проблемы...

Спасибо за вашу помощь!

2 ответов


быстрое решение, вы должны поместить NSInteger const TXT_NAME = 1; в константы.h, и не нужно ничего в константах.м.

причина: Если вы установите значение константы в .m, он не виден другими единицами перевода, которые включают только .H-файл. Значение константы должно быть известно во время компиляции, чтобы ее можно было использовать в case внутри switch.

обновление:

вышеизложенное работает при компиляции в Objective-C++. Вам нужно, чтобы ваши файлы заканчивались .mm вместо .m для их компиляции в Objective-C++ вместо Objective-C.

чтобы работать в Objective-C, вы должны определить свою константу либо так:

#define TXT_NAME 1

или еще лучше вот так:

enum {TXT_NAME = 1};


Я обычно следую за тем, что Apple, похоже, делает, и определяю перечисление typedef в .H-файл, как это.

typedef NS_ENUM(NSInteger, PSOption) {
  PSOption1,
  PSOption2,
  PSOption3,
  PSOption4,
};  

затем вы можете использовать его в своем заявлении case и даже передать его в функции, а также тип, например

- (void)myMethod:(PSOption)option;

еще одно преимущество этого над #define завершение кода и компилятор проверки