Swift 仅将协议限制在某些类型的类中

Posted

技术标签:

【中文标题】Swift 仅将协议限制在某些类型的类中【英文标题】:Swift confine protocol to certain types of class only 【发布时间】:2017-08-17 20:25:49 【问题描述】:

我有一个协议,我只分配给 SKScene 对象。这基本上是为了让我可以强制执行某些属性和方法,让我创建一个管理器类,知道我的场景都可以做某些事情。例如,我可以创建一个教程场景和一个级别 1、级别 2 等。

  protocol GameSceneProtocol  
        func performAction()
  

所以现在在我的经理中,我有一个用于场景的弱变量(经理在场景中初始化)

 weak var scene: SKScene?

我遇到的问题是我想调用与 SKScene 相关但也与我的协议相关的方法。例如

 scene.addChild(modal)
 scene.performAction()

我真正想做的是:

weak var scene: SKScene, GameSceneProtocol

我使用这个管理器的原因是因为我需要向我的场景添加不同的模态视图(同样是教程和关卡),然后根据在这些模态中采取的操作运行通用代码。这些模式和功能在不同的场景中是相同的,这就是我尝试将它们移动到单独的类的原因。

有没有一种方法可以确保属性属于特定类型但也符合协议?

我觉得我的设计在这里是错误的,我应该有更好的方式来构建它。可能创建我的实际场景继承自而不是协议的基本场景类。这样我就可以避免重复相同的代码。

【问题讨论】:

【参考方案1】:

你想要的是一个子类

class SKSceneWithProtocol : SKScene, GameSceneProtocol

但此时协议本质上是没有意义的,你还不如直接在子类中编写代码。

您的另一个选择是在需要时将场景投射到协议中

if let sceneProtocol = scene as? GameSceneProtocol

    //do stuff here

【讨论】:

我刚刚对我的帖子进行了编辑,说我可能应该按照你发布的那样做!我想我只是想避免返工 - 这是一个爱好项目,我并没有真正预先计划结构 - 这又回来咬我了! 这发生在我们所有人身上。【参考方案2】:

您可以使用协议组合来定义一个属性,其中对象必须是SKSceneGameSceneProtocol。由于协议组合适用于协议(而非类),因此您还必须定义一个空的 SKSceneProtocol 并通过扩展将该一致性添加到 SKScene

protocol SKSceneProtocol  
extension SKScene: SKSceneProtocol  

protocol GameSceneProtocol  ... 

var object: (SKSceneProtocol & GameSceneProtocol)? = nil

【讨论】:

“由于协议组合只适用于协议(而不是类),”在 Swift 4 中不是这样 现在为什么不扩展 SKScene 以采用 GameSceneProtocol? 我投了赞成票,因为我从来不知道这可以通过协议来完成,但我似乎无法在操场上让它工作。您能否提供一个更详细的示例来说明它的工作原理。

以上是关于Swift 仅将协议限制在某些类型的类中的主要内容,如果未能解决你的问题,请参考以下文章

Swift 协议:我可以限制关联类型吗?

在 swift 中使用协议作为数组类型和函数参数

Swift无法使用类型(实例)访问类中的静态变量

NSExtension - 分享 - 仅将类型限制为视频或图片

Swift 3 扩展限制为一个类型

符合两种协议的Swift泛型类型