Классы стиля Java-enum в Objective-C?

Я новичок в Obj-C, поэтому простите меня, если это глупый вопрос:

Как я могу реализовать некоторые в стиле Javas перечислений? Или, если быть более точным:

Мне нужен класс с некоторыми известными свойствами, которые являются фиксированными во время компиляции и уникальными для каждого экземпляра. Кроме того, мне нужен только один тип экземпляра.

Позвольте мне привести пример в Java:

public enum MessageTypes {
  DEFAULT("white", "standard", 1),
  EXPRESS("red", "expressMessage", 2),
  BORADCAST("green", "broadcast", 3);

  String color; String tagName; int dbId;
  MessageTypes(String color, String tagName, int dbId) {
    // you get the idea
  }
  //some methonds like getEnumByTagName
}

Как бы вы сделали что-то подобное в Objective-C? Я что-то упускаю? Это плохой шаблон?

Спасибо заранее!

ИЗМЕНИТЬ: Прошу прощения, если бы я не поняла. Я знаю, что obj-c перечисления не то, что я ищу (поскольку они только немного больше, чем typedef для int).

Я хотел бы создать набор экземпляров определенного типа (однотипных, неизменяемых). Одноэлементный шаблон в Apples Dev-Docs бесполезен, так как я хочу, чтобы несколько разных экземпляров класса каждый с отдельными значениями в своих свойствах.

Цель состоит в том, чтобы иметь несколько типов сообщений (около 20), которые могут быть назначены для Message как свойство. Каждый из моих типов сообщений имеет (фиксированный и предопределенный) цвет, значение атрибута (в XML-представлении) и числовой идентификатор.

В Java я бы использовал перечисление, как в моем примере кода. Но как создать различные MessageTypes и связать их с их свойствами в Obj-C?

Создание 20 подклассов MessageType (каждый из которых имеет одноэлементный экземпляр, содержащий свойства), похоже, очень много работает для такой простой задачи и полного переполнения.

Мой текущий подход заключается в создании класса с NSArray, в котором хранятся разные экземпляры. При первом доступе к методу, подобному +(id)messageTypeForId:NSInteger id_, NSArray предварительно заполняется. Но это кажется совершенно неуклюжим и вовсе не элегантным...

Есть ли более удовлетворительный подход?

Ответы

Ответ 1

Существует не так много способов "более удовлетворительного подхода".

Обычным шаблоном Cocoa будет создание таких методов, как:

+ (MessageTypes*) sharedDefaultMessageType;
+ (MessageTypes*) sharedExpressMessageType;
+ (MessageTypes*) sharedBroadcastMessageType;
etc

а затем выполните их как:

+ (MessageTypes*) sharedDefaultMessageType
{
   static MessageTypes* thisMessageType = nil;
   if ( !thisMessageType ) {
      thisMessageType = [[MessageTypes alloc] initWithColor:@"white" tagName:@"standard" dbId:1];
   }
   return thisMessageType;
}

В качестве альтернативы, сохранение общего типа MessageType * в NSMutableArray или NSMutableDictionary или предварительное вычисление их по мере того, как вы делаете, являются одинаково действительными approraches.

Обратите внимание, что вышеупомянутый метод "шаблон" может быть сгенерирован с помощью макроса, который можно записать в файле .m:

CREATEMESSAGETYPE( Default, @"white", @"standard", 1 )
CREATEMESSAGETYPE( Express, @"red", @"expressMessage", 2 )
CREATEMESSAGETYPE( Broadcast, @"green", @"broadcast", 3 )

который может быть "более удовлетворительным" или более уродливым, в зависимости от вашей точки зрения.

Ответ 2

Я думаю, что просто использую стандартный C-enum:

typedef enum { MT_WHITE, MT_RED, MT_GREEN } MessageType;

Затем вы просто используете его, как и любой другой тип данных:

@interface Blah {}

-(void) setMessageType:(MessageType)newMessageType;

@end

Ответ 3

Перечисления не являются объектами в C, и, следовательно, не в Objective-C. Это просто пользовательские скаляры, которые имеют ограниченный набор именованных значений, которые они могут принимать. Вы можете указать свойства объекта, которые являются перечисляемыми типами, которые, по моему мнению, ближе всего к тому, что вы ищете.

Если вам нужно что-то конкретное выполнить с помощью этой функции, вы можете отредактировать сообщение, чтобы указать, что это такое.

Ответ 4

У меня был тот же вопрос более или менее, но найти все вышеупомянутые решения неуклюже стилистически. В частности, когда вы просто используете свойство C enum для объекта, вы теряете одноэлементную семантику перечислений Java. Самая большая свобода, которую я обнаружил при использовании перечислений Java, заключается в том, что экземпляры перечисления представляют собой одноэлементные подклассы и поэтому участвуют в полиморфизме методов. Еще более мощным, чем перечисления с уникальными атрибутами, являются перечисления с полиморфным поведением.

Учитывая, что это ключевая функция, с которой я столкнулся, кластер класса Objective-C с отдельными подклассами singleton - это подход с желаемым поведением, несмотря на то, что он немного отстает от стоимости и сложности реализации?