gpt4 book ai didi

ios - 强制模板成为协议(protocol)

转载 作者:行者123 更新时间:2023-11-28 06:16:20 24 4
gpt4 key购买 nike

如何确保给定的模板参数是协议(protocol)?

GKEntity 有一个名为component(ofType: class) 的函数,我想添加component(ofProtocol: Protocol)。它看起来像这样:

extension GKEntity {
func component<T: Protocol>(ofProtocol: T) -> T? {
return self.components.first() { component in
return component.conforms(to: ofProtocol)
} as? T
}
}

我想在一个包含对实体的引用的组件中使用它,如下所示:

let component = self.entity?.component(ofProtocol: SpriteComponentProtocol)

但不知何故我总是得到:

显示所有消息

Cannot convert value of type 'SpriteComponentProtocol.Protocol' to expected argument type 'Protocol'

更新:

我的想法是我有一个 Sprite 组件:

protocol SpriteComponentProtocol {
var spriteNode: SKSpriteNode { get set }
}

class SpriteComponent: GKComponent {
var spriteNode: SKSpriteNode?
}

控件的另一个组件:

protocol PlayerControlComponentProtocol {
var steerAngle: Double { get set }
}

class PlayerControlComponent: GKComponent, PlayerControlComponentProtocol {
var steerAngle: Double = 90.0

override func update(deltaTime seconds: TimeInterval) {
//here i do manipulate the spriteComponent.spriteNode
let comp = self.entity?.component(ofProtocol: SpriteComponentProtocol)
}
}

我希望能够随时更换 SpriteComponent。

最佳答案

您的代码的问题是 Protocol是描述 Obj-C 协议(protocol)的不透明类型,所以如果你想桥接 SpriteComponentProtocol.self到此为止,你需要标记SpriteComponentProtocol作为@objc (但即使你这样做了;你也无法转换为 T ,因为返回的实例不是 Protocol 类型)。

但话虽如此,您不需要使用 Obj-C Protocol输入或 conforms(to:)这里的方法,你可以简单地使用条件类型转换运算符 as?component(ofType:) 的过载中没有 GKComponentT 的约束:

extension GKEntity {

func component<T>(ofType type: T.Type) -> T? {
return self.components.lazy.flatMap{ $0 as? T }.first
}
}

我们正在使用 lazy这里是为了避免评估所有 components , 然后 flatMap(_:)first为了获得第一个可转换为 T 的元素(在 T 是协议(protocol)类型的情况下,这为我们提供了符合协议(protocol)的第一个元素)。

然后您可以像这样简单地使用它:

protocol SpriteComponentProtocol {
var spriteNode: SKSpriteNode { get set }
}

class PlayerControlComponent: GKComponent {

override func update(deltaTime seconds: TimeInterval) {
let comp = self.entity?.component(ofType: SpriteComponentProtocol.self)
}
}

在 Swift 4 中,您可以完全删除此重载,而只需调用 GKEntity component(ofType:) 具有类存在元类型的方法:

let comp = self.entity?.component(ofType: (GKComponent & SpriteComponentProtocol).self)

如现在T满足: GKComponent约束。然后您可以同时访问 GKComponent方法和 SpriteComponentProtocol解包实例的协议(protocol)要求。

关于ios - 强制模板成为协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45032278/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com