为什么我不能在 iOS9 中设置 GKAgent2D 的速度?

Why can't I set the speed of a GKAgent2D in iOS9?

如果我尝试在 iOS9 中更改 GKAgent2D(或其父 class GKAgent)的速度参数值,我会收到此无法识别的选择器错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GKAgent2D setSpeed:]: unrecognized selector sent to instance

但是在 iOS10 中不会发生此错误并且代理的速度已正确更改。

我可以在一个非常简单的示例中重现该错误(单视图 iOS 应用程序,将视图控制器代码更改为以下内容,请注意,错误发生在 GKAgent2D 或 GKAgent 中):

import UIKit
import GameplayKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var agent = GKAgent()
        agent.speed = 10

        print(agent.speed)
    }

}

上面总是在模拟器上设置代理速度的行上出现这个无法识别的选择器错误而崩溃 运行 iOS9.3,但不是 iOS10.3(所有这些Xcode 8.3.2).

GKAgent 的速度 属性 被记录为读写并在 iOS9 下得到支持 - 参见 Apple's Documentation for GKAgent, speed Property

我在使用 GKAgentDelegate 时遇到了类似的问题,它会在 iOS9 上崩溃,仅当 agentWillUpdate 的选择器无法识别时。我通过在我的代码中放置一个虚拟方法来解决这个问题:

func agentWillUpdate(_ agent: GKAgent) {
}

我尝试了一个类似的新错误解决方案,通过覆盖我的 GKAgent2D 子 class 中的速度 属性 并提供明确的 setter 和 getter,甚至按照 Kdawg 的建议通过私有 Float 支持速度参数,但是当设置 super 的速度参数时仍然会出现相同的错误:

class Agent:GKAgent2D {
    override var speed:Float {
        get {return localSpeed}
        set {localSpeed = newValue}
    }
    private var localSpeed:Float {
        get {return super.speed}
        set {super.speed = newValue}
    }
}

有什么想法吗?

具体来说:iOS9 中的 GKAgent 关于选择器是否存在任何已知问题?

或者,有没有关于替代解决方案的想法?

如果可以的话,我愿意支持iOS9。在我看来它像是 GameplayKit 中的一个错误 - 但我希望 Apple 对报告的回应是它已在 iOS10.

中修复

已编辑

我的意思是让你的子 class 的 属性 setter/getter 只是覆盖基础 class 而不是尝试访问父 class 根本就是 setter,像这样:

class Agent:GKAgent2D {
    private var _speed: Float = 0.0 
    override var speed:Float {
        get {return _speed}
        set {_speed = newValue}
    }
}

此时,假设GKAgentGKAgent2d通过其属性getter访问speed,它将得到[=的值16=] 来自您的子 class 中被覆盖的 getter。这就是为什么我在评论中建议在制作 subclass:

之后尝试这个
var agent: GKAgent 
agent = GKAgent2dSubType()
agent.speed = 10

然后我希望如果您随后尝试读出您的 GKAgent 代理的 属性,它将是 10。因此您的代理的预期行为可能与您的那里的速度。


原创 这只是一个完全的猜测(我不太熟悉这里的技术),但你有没有尝试改变你的

override var speed:Float {
    get {return super.speed}
    set {self.speed = newValue}
}

不要引用 super.speedself.speed(顺便说一句,不应该从 speed setter 中设置 self.speed 导致无限递归调用setter?) 而是引用私有支持浮点值?那么也许您将能够实例化一个类型为 GKAgent2dSubClass 的对象(但是您已将其命名为子 class)并让它工作。