2012-02-02 15 views
14

Tworzę protokół, a jednym z parametrów metody, którą definiuję, jest CMTime*. Chciałbym przekazać deklarację CMTime, w przeciwieństwie do jej włączenia. Jednak próbowałem @class CMTime i narzeka, że ​​jest ponownie zdefiniowany w innym miejscu jako inny typ symbolu. Dokumentacja mówi, że to jest struktura. Próbowałem już naprzód, deklarując to jako , ale wciąż narzeka, że ​​nie wie, co to jest.Przekaż dalej struct w Objective-C

Jakieś pomysły, co robię źle?

+2

Niestety, deklaruje się to przy użyciu anonimowej struktury. Oznacza to, że musisz skopiować całą deklarację (i mam nadzieję, że nigdy się nie zmieni) lub po prostu dołączyć nagłówek. – ughoavgfhw

+1

@ughoavgfhw kopiowanie go nie jest dobre (są szanse, że obie deklaracje zakończą się w tej samej TU). Poza tym, myślę, że kwalifikuje się jako konkretna odpowiedź, biorąc pod uwagę sposób, w jaki "CMTime" zostało zadeklarowane. – justin

+0

@Justin I zasugerowałem tylko dlatego, że on powiedział, że nie zamierza włączyć nagłówka, ale teraz, gdy o tym myślę, dostał błąd, który został już zdefiniowany podczas próby utworzenia klasy, co sugerowałoby nagłówek został już uwzględniony. Jeśli ktoś może to wyjaśnić, mogę napisać to jako odpowiedź. – ughoavgfhw

Odpowiedz

0

Jeśli chcesz, aby pliki, które mają deklarację przekazania, wiedziały o zawartości struktury, muszą albo zaimportować nagłówek (może on być w wielu miejscach), gdzie jest zdefiniowany. Możesz może forward zadeklarować struct, jeśli nie potrzebujesz dostępu do jego właściwości, ale to jest jego zasięg.

+0

Przepraszam (muszę nauczyć się używać google: P) - edycja odpowiedzi już teraz. Czy moja odpowiedź jest teraz poprawna? – jrtc27

+0

dotarcie tam - to bardziej skomplikowane. – justin

17

Źródło skompilowane jako ObjC ma takie same zasady jak C w tym zakresie.

Źródło skompilowane jako ObjC++ ma takie same zasady jak C++ w tym zakresie.

@class MONClass; to zaawansowana deklaracja typu ObjC. Nie używaj go dla struktur.

struct t_mon_struct; to deklaracja typu forward o nazwie o nazwie struktura C lub C++. Nie używaj go do typów ObjC. Technicznie, kompilator pozwala również na forwardowanie deklaracji klasy C++ jako struktury (oczywiście pod warunkiem, że klasa jest również zadeklarowana w globalnej przestrzeni nazw).

Tak więc korzeń semantyki wszystko sprowadza się do C (zakładając, że jest to tłumaczenie ObjC). Przestanę wspominać teraz o ObjC i C++.

Istnieją pewne wspólne źródła złożoności tutaj:

  • namespace struct
  • deklaracja struct za
  • unikając wielu definicje etykiet

struct t_mon_struct; to naprzód deklaracja oznaczonego struct. W szczególności jest to nazwa, której nazwa istnieje w strukturze przestrzeni nazw.

oznaczonego struct, który istnieje w przestrzeni nazw struct:

struct t_mon_struct { int a; }; 

anonimowy struct z typedef w globalnej przestrzeni nazw:

typedef struct { int a; } t_mon_struct; 

oznaczonego struct z typedef w globalnej przestrzeni nazw:

typedef struct t_mon_struct { int a; } t_mon_struct; 

CMTime jest zadeklarowany w następujący sposób:

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

Konkretnie, globalny etykieta typedef CMTime jest zobowiązany do anonimowej struktury w obszarze nazw struct, i nie może się odwoływać, jeżeli jego deklaracja jest widoczny.

Gdyby CMTime zostały uznane:

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

następnie można zdobyć za pomocą przodu deklarację struct CMTime:

struct CMTime; 
void foo(struct CMTime*); 

Ponieważ nie został uznany w ten sposób, musisz #include deklarację lub wymyślić obejście.

Komplikacje pogarszają się, gdy typedef struktury struct różni się od tagu. Nie można powiązać ani redeclare typedef (w C). Można się jednak do niego przekraść, używając nazwy w nazewnictwie struct - które niektórzy autorzy biblioteki uważają za prywatne.

1

Po prostu dodaje typedef zanim struct zrobi dla mnie sztuczkę.

typedef struct CMTime;