Objective-C - определить перечисление, которое может быть точкой, называемой как ENUMTYPE.ENUMVAL - PullRequest
7 голосов
/ 16 января 2011

Я прочитал много вещей о типах enum в target-c, и я вижу, что есть много способов их определить. Но я не вижу правильного способа (если он есть) определить перечисление, которое можно вызвать с помощью CARS.ROLLSROYCE и которое нельзя использовать только с ROLLSROYCE в коде.

Таким образом, я могу определить ROLLSROYCE в перечислении CARS, а также в перечислении BEAUTIFULCARS.

Знаете ли вы, как определить такое перечисление?

Ответы [ 2 ]

3 голосов
/ 16 января 2011

Вы пытаетесь реализовать пространства имен для своих перечислений в Objective-C. То, что вы просите, это много смазки локтя в Objective-C. Вероятно, вам лучше всего использовать C ++ для этого, поскольку он легко и полностью поддерживается в любом приложении iOS или Cocoa. Вам придется переименовывать файлы, которые #import ваш код C ++, в .mm файлы вместо .m файлов, и компилятор C ++ может быть хитрее, чем Objective-C. По этому маршруту вы создадите заголовочный файл, например Enums.h.

//  Enums.h
namespace CARS
{
    enum CARS
    {
        ROLLSROYCE
    };
}
namespace BEAUTIFULCARS
{
    enum BEAUTIFULCARS
    {   
        ROLLSROYCE = 45
    };
}

И в вашем .mm исходном файле

#import "Enums.h"

-(void)printEnumvals
{
    NSLog(@"CARS %d BEAUTIFULCARS %d",
                     CARS::ROLLSROYCE,
            BEAUTIFULCARS::ROLLSROYCE);
}

Если вы хотите избежать использования C ++ для этого решения, вам понадобится гораздо больше смазки для локтя, бухгалтерии и возможностей для ошибок. Для этого вам понадобится заголовок и исходный файл.

// CARS.h
@interface BEAUTIFULCARS : NSObject
{
    enum
    {
        BEAUTIFULCARS_ROLLSROYCE = 45
    } BEAUTIFULCARS;
}
@end
@interface CARS : NSObject
{
    enum
    {
        CARS_ROLLSROYCE
    } CARS;
}
@end

// CARS.m
@implementation BEAUTIFULCARS
+(NSInteger)ROLLSROYCE{ return BEAUTIFULCARS_ROLLSROYCE; }
@end
@implementation CARS
+(NSInteger)ROLLSROYCE{ return CARS_ROLLSROYCE; }
@end

Ваш .m источник почти такой же:

#import "CARS.h"

-(void)printEnumvals
{
    NSLog(@"CARS %d BEAUTIFULCARS %d",
                     CARS.ROLLSROYCE,
            BEAUTIFULCARS.ROLLSROYCE);
}

Objective-C не управляет областью так же, как большинство других языков ОО. Интерфейсы определяют свойства и сообщения, которые поддерживает объект, который поддерживает интерфейс, но не поддерживают уровни защиты, такие как публичные или частные. Когда вы определяете перечисление в @interface, это перечисление попадает в глобальную область видимости.

1 голос
/ 30 июня 2012

В моем случае я не хотел использовать пространства имен C ++ или писать избыточные классы Objective-C для такого простого случая, поэтому я вернулся к C.

// Enum.h
typedef struct 
{
   const int ROLLSROYCE;
} _CARS;

typedef struct 
{
   const int ROLLSROYCE;
} _BEAUTIFULCARS;

extern const _CARS CARS;
extern const _BEAUTIFULCARS BEAUTIFULCARS;

А затем в Enum.m определить значения

// Enum.m    

#import "Enum.h"

const _CARS CARS = {0};// 0 is to be assigned to ROLLSROYCE field in struct
const _BEAUTIFULCARS BEAUTIFULCARS = {1}; // same but with 1

И, наконец, в вашем "основном" коде

#import "Enum.h"

// Some method
{
  NSLog(@"I can refer to CARS.ROLLSROYCE = %d and BEAUTIFULCARS.ROLLSROYCE = %d", CARS.ROLLSROYCE, BEAUTIFULCARS.ROLLSROYCE);
}

Который будет производить этот вывод:

I can refer to CARS.ROLLSROYCE = 0 and BEAUTIFULCARS.ROLLSROYCE = 1
...