Вперед объявите структуру в Objective-C

Я создаю протокол, и один из параметров метода, который я определяю, - это CMTime*. Я хотел бы направить объявление CMTime, а не включать его. Тем не менее, я пробовал @class CMTime, и он жалуется, что он переопределен в другом месте как другой тип символа. Документация говорит, что это структура. Я пробовал переслать его как

struct CMTime;

но он все еще жалуется, что он не знает, что это такое.

Любые идеи, что я делаю неправильно?

Ответы

Ответ 1

Источник, скомпилированный как ObjC, имеет те же правила, что и C в этом отношении.

Источник, скомпилированный как ObjС++, имеет те же правила, что и С++ в этом отношении.

@class MONClass; является прямым объявлением типа ObjC. Не используйте его для структур.

struct t_mon_struct; является прямым объявлением именованной структуры C или С++. Не используйте его для типов ObjC. Технически компилятор позволяет вам также переслать объявление класса С++ как структуры (если конечно класс также объявлен в глобальном пространстве имен).

Таким образом, корень семантики все сводится к C (предполагая, что это преобразование ObjC). Я перестану упоминать ObjC и С++ сейчас.

Здесь есть некоторые общие источники сложности:

  • пространство имен struct
  • объявление структуры
  • избегать множественных определений меток

struct t_mon_struct; является прямым объявлением тегированной структуры. В частности, это имя, которое существует в пространстве имен struct.

тегированная структура, которая существует в пространстве имен struct:

struct t_mon_struct { int a; };

анонимная структура с typedef в глобальном пространстве имен:

typedef struct { int a; } t_mon_struct;

помеченная структура с типом в глобальном пространстве имен:

typedef struct t_mon_struct { int a; } t_mon_struct;

CMTime объявляется следующим образом:

typedef struct
{
    CMTimeValue    value;
    CMTimeScale    timescale;
    CMTimeFlags    flags;
    CMTimeEpoch    epoch;
} CMTime;

В частности, глобальная метка typedef CMTime привязана к анонимной структуре в пространстве имен struct и может не ссылаться, если только ее объявление не отображается.

Было объявлено CMTime:

typedef struct CMTime
{
    CMTimeValue    value;
    CMTimeScale    timescale;
    CMTimeFlags    flags;
    CMTimeEpoch    epoch;
} CMTime;

то вы могли бы получить с помощью форвардного объявления struct CMTime:

struct CMTime;
void foo(struct CMTime*);

Так как он не был объявлен таким образом, вам нужно #include его объявление или разработать обходное решение.

Усложнения ухудшаются, когда struct typedef отличается от его тега. Вы не можете связывать или переопределять typedef (в C). Однако вы можете прокрасться вокруг него, используя имя в пространстве имен struct, которое некоторые авторы библиотеки считают закрытыми.

Ответ 2

Просто добавив typedef, прежде чем структура сделает трюк для меня.

typedef struct CMTime;

Ответ 3

Если вы хотите, чтобы файлы, имеющие объявление вперед, знали о содержимом структуры, им нужно либо импортировать заголовок (он может быть в нескольких местах), где он определен. Вы можете перенаправить объявление struct, если вам не нужно обращаться к его свойствам, но это его размер.