我尝试了很多组合,但问题仍然存在。我不明白为什么 Swift 不能编译以下代码。我已经使用了多种变体(使用“where”来约束协议(protocol)、在协议(protocol)内移动 setter 和 getter 等...)仍然没有运气。你能看出问题出在哪里吗?
// GameScene.swift
import SpriteKit
extension SKSceneDelegate { // adding 'where Self: Game'
// causes err to moves somewhere else
var playerDirection: PlayerDirection { get set } // doesn't like this!
}
class GameScene: SKScene {
override func keyDown(theEvent: NSEvent) {
switch (theEvent.keyCode) {
case 123:
delegate!.playerDirection = .Left;
case 124:
delegate!.playerDirection = .Right;
default:
break
}
}
}
// SomeGame.swift
import Foundation
import SpriteKit
class Game: NSObject, SKSceneDelegate {
var _playerDirection: PlayerDirection = .None
// moving that code to the protocol, compiler can't find _playerDirection
var playerDirection: PlayerDirection {
set {
_playerDirection = newValue
}
get {
return _playerDirection
}
}
lazy var scene: GameScene = {
let scene = GameScene(size: CGSizeMake(CGFloat(100), CGFloat(100)))
scene.delegate = self
return scene
}()
func update(currentTime: NSTimeInterval, forScene scene: SKScene) {
}
}
// PlayerControlComponent.swift
import Foundation
enum PlayerDirection {
case None, Left, Right, Down, Up
}
最佳答案
我认为您从错误的角度处理问题。看起来您想要的是能够从 GameScene
中的 keyDown()
函数访问 playerDirection
。您可能应该检查 GameScene 中的
是一个 delegate
属性,而不是尝试将 playerDirection
设为 SKSceneDelegate
协议(protocol)的属性Game
,如果是,则将 delegate
转换为 Game
,以便 playerDirection
属性可供您使用。
您可以使用 if let
和 as?
运算符非常轻松地做到这一点,如下所示:
override func keyDown(theEvent: NSEvent) {
if let game = delegate as? Game {
switch (theEvent.keyCode) {
case 123:
game.playerDirection = .Left;
case 124:
game.playerDirection = .Right;
default:
break
}
}
}
这非常好,因为现在您还要在使用之前检查以确保 delegate
确实存在。如果在调用该函数之前未设置 delegate
,则像之前那样强行展开它可能会导致运行时异常。
关于swift - 如何使用 var 扩展委托(delegate)实现的现有协议(protocol)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35975674/