转发在Objective-C中声明一个结构

use*_*226 14 c struct objective-c forward declare

我正在创建一个协议,我正在定义的方法的参数之一是CMTime*.我想转发声明CMTime,而不是包括它.但是,我试过@class CMTime并且它抱怨它在其他地方重新定义为不同类型的符号.文档说这是一个结构.我已经尝试过将其声明为

struct CMTime;
Run Code Online (Sandbox Code Playgroud)

但它仍在抱怨它不知道它是什么.

我有什么想法我做错了吗?

jus*_*tin 18

在这方面,编译为ObjC的源具有与C相同的规则.

编译为ObjC++的源在这方面与C++具有相同的规则.

@class MONClass;是ObjC类型的前向声明.不要将它用于结构.

struct t_mon_struct;指定的 C或C++结构的前向声明.不要将它用于ObjC类型.从技术上讲,编译器允许您将C++类声明为结构(当然,该类也在全局命名空间中声明).

因此,语义的根源都归结为C(假设这是一个ObjC转换).我现在不再提及ObjC和C++了.

这里有一些常见的复杂因素:

  • struct命名空间
  • 结构的声明
  • 避免多个标签定义

struct t_mon_struct;是标记结构的前向声明.具体来说,它的名称存在于struct namespace中.

存在于struct命名空间中的标记结构:

struct t_mon_struct { int a; };
Run Code Online (Sandbox Code Playgroud)

全局命名空间中具有typedef的匿名结构:

typedef struct { int a; } t_mon_struct;
Run Code Online (Sandbox Code Playgroud)

全局命名空间中带有typedef的标记结构:

typedef struct t_mon_struct { int a; } t_mon_struct;
Run Code Online (Sandbox Code Playgroud)

CMTime 声明如下:

typedef struct
{
    CMTimeValue    value;
    CMTimeScale    timescale;
    CMTimeFlags    flags;
    CMTimeEpoch    epoch;
} CMTime;
Run Code Online (Sandbox Code Playgroud)

具体来说,全局typedef标签CMTime绑定到struct命名空间中的匿名结构,除非其声明可见,否则不能引用它.

CMTime被宣布为:

typedef struct CMTime
{
    CMTimeValue    value;
    CMTimeScale    timescale;
    CMTimeFlags    flags;
    CMTimeEpoch    epoch;
} CMTime;
Run Code Online (Sandbox Code Playgroud)

那么你可以通过使用前向声明获得struct CMTime:

struct CMTime;
void foo(struct CMTime*);
Run Code Online (Sandbox Code Playgroud)

由于它没有这样声明,你需要#include声明它,或者设计一个解决方法.

当struct的typedef与其标签不同时,复杂性会恶化.您无法绑定或重新声明typedef(在C中).但是,您可以使用struct命名空间中的名称来隐藏它 - 一些库作者认为这是私有的.


jrt*_*c27 0

如果您希望具有前向声明的文件了解结构的内容,则它们需要导入定义它的标头(它可以位于多个位置)。如果不需要访问结构体的属性,则可以转发声明该结构体,但这就是它的范围。