Переопределение / расширение typedef, определенного в протоколе Objective C, в классе, соответствующем протоколу - PullRequest
6 голосов
/ 04 августа 2010

У меня есть протокол Objective-C:

typedef enum {
    ViewStateNone
} ViewState;

@protocol ViewStateable

- (void)initViewState:(ViewState)viewState;
- (void)setViewState:(ViewState)viewState;

@end

Я использую этот протокол в следующем классе:

#import "ViewStateable.h"

typedef enum {
    ViewStateNone,
    ViewStateSummary,
    ViewStateContact,
    ViewStateLocation
} ViewState;

@interface ViewController : UIViewController <ViewStateable> {

}

@end

Я не буду слишком вдаваться в специфику моего приложения, но то, что я здесь делаю, это typedef перечисление в протоколе, чтобы методы протокола могли принимать входные значения этого типа.

Затем я надеюсь переопределить или расширить эту typedef в классах, которые соответствуют этому протоколу, чтобы каждый класс мог иметь свои собственные состояния просмотра. Однако я сталкиваюсь со следующими двумя ошибками:

  1. Redeclaration of enumerator 'ViewStateNone'
  2. Conflicting types for 'ViewState'

Мне стыдно признаться, что мои знания C (а именно typedef s) не обширны, поэтому то, что я пытаюсь сделать здесь, во-первых, возможно и, во-вторых, разумно?

Приветствую друзей.

Ответы [ 2 ]

7 голосов
/ 04 августа 2010

Это не возможно или разумно.Это происходит из-за того, что typedefs и перечисления в основном просто определяют.(Ну, не совсем, но для этого они есть.) Если вам нужно сделать что-то подобное, вы можете пересмотреть свой дизайн (см. Ниже).


Подробнее

typedef type newtype;

(почти) эквивалентно

#define newtype type;

, а

enum {
  ViewStateNone
};

в основном совпадает с

#define ViewStateNone 1

Есть несколько более тонких моментов в отношении различий между ними, и наиболее убедительным аргументом в пользу использования enum и typedefs является, конечно, проверка целочисленных констант во время компиляции.как только замечено typedef enum {} type;, его нельзя увидеть, и как только оно увидено, его имя зарезервировано для него и только для него.

Есть способы обойти это;но это пути, по которым редко ходят, и, как правило, не зря.Это быстро становится невероятно неуправляемым.

В качестве решения вы, возможно, захотите создать новый класс MyViewState, который представляет состояние просмотра и связанную информацию, которая может легко обернуться вокруг NSInteger.


В заключение: Просмотрите свой дизайн.Боюсь, вы делаете что-то слишком запутанное.

1 голос
/ 04 августа 2010

Это, конечно, невозможно в той форме, в которой вы ее имеете, по причинам, которые ошибки довольно кратко объясняют. Константа enum может быть объявлена ​​только один раз в любой области видимости, а также typedef.

Кроме того, существует некоторая концептуальная проблема с определением типа в протоколе, который разработчики могут затем переопределить. Разработчики должны соответствовать типу, а не добавлять к нему. Если класс должен иметь возможность определять свой собственный набор значений, протокол должен использовать тип, который является достаточно общим, чтобы содержать все те, которые могут быть необходимы. В этом случае вы можете использовать int или, возможно, более разумно, что-то читаемое, как NSString. Вы также можете добавить в протокол другой метод, который будет сообщать значения, поддерживаемые реализующим классом.

...