我是 Objective-c 的新手,所以请多多包涵,我仍在尝试弄清楚可以在 Objective-C 中放置属性和类变量的众多地方。
我是一位经验丰富的 Metal 开发人员,但我几乎没有使用 objective-c 做过任何事情。
我正在尝试创建一个 MetalCore 类,它将保存 MTLDevice、MTLCommandQueue 并促进应用程序核心管道等的创建。
因此我定义了以下内容
@property (readonly, nonatomic, assign) MTLDevice* devicePtr;
但是在我的类里面我得到错误 Unknown type name MTLDevice; did you mean...
即使我#import <Metal/Metal.h>
那么这里发生了什么?
我查看了堆栈溢出并找到了人们像这样定义函数的例子
- (<MTLDevice> *)device;
或
- (instancetype)initWithDevice:(id<MTLDevice>) device;
整个 id 和 <> 是怎么回事?什么情况下可以省略id部分?
我觉得特别奇怪的是,虽然大多数 Metal 类型似乎都需要 id,但有些像 MTLRenderPipelineDescriptor
不需要它,实际上只适用于 Type*
模式。这是为什么?我如何确定文档中需要什么?
最佳答案
在 Objective-C 中,id
基本上表示“任何对象类型”。如果要确保对象符合协议(protocol)(例如MTLDevice
),则在声明其类型时在id
之后的尖括号中指定协议(protocol):id<MTLDevice>
表示“符合MTLDevice
的类型”协议(protocol)”。
与具体类(例如MTLRenderPipelineDescriptor
)不同,您不会在 id 后使用*
,因此您不会写id<MTLDevice> *
(除非您使用指向设备的指针,这并不常见). MTLDevice *
没有意义,因为MTLDevice
不是具体类型。 <MTLDevice>
本身是无稽之谈,是语法错误,<MTLDevice> *
也是如此。
来自 Swift,您可能习惯于将协议(protocol)和具体类型混为一谈,因为 Swift 不会在“符合协议(protocol)的某种类型”和“某种具体类型”之间进行句法区分。要判断某物是否是协议(protocol),请查阅文档;它会明确指出什么时候是协议(protocol)。在 Metal 中,所有“描述符”类型都是具体的(例如,MTLRenderPipelineDescriptor
),而大多数其他对象类型是在协议(protocol)后面抽象的(MTLDevice
、MTLCommandQueue
、MTLLibrary
、MTLFunction
、MTLTexture
、MTLRenderPipelineState
”、MTLCommandBuffer
等)
关于ios - id<> 需要 MTLDevice 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51854316/