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

时间:2017-07-08 20:22:04

标签: ios gamekit

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

  

***由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:' - [GKAgent2D setSpeed:]:无法识别的选择器发送到实例

但是在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遇到了类似的问题,只有使用无法识别的agentWillUpdate选择器才能在iOS9上崩溃。我通过在我的代码中添加一个虚拟方法来解决这个问题:

func agentWillUpdate(_ agent: GKAgent) {
}

我尝试了一个类似的新错误解决方案,通过覆盖我的GKAgent2D子类中的speed属性并提供显式的setter和getter,甚至按照Kdawg建议的私有Float支持speed参数,但是同样的设置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中得到修复。

1 个答案:

答案 0 :(得分:2)

<强>被修改

我的意思是让您的子类的属性setter / getter覆盖基类,而不是尝试访问父类的setter,如下所示:

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

此时,假设GKAgentGKAgent2d通过其属性getter访问speed,它将从子类中重写的getter获取_speed的值。这就是为什么我在评论中建议在创建子类之后尝试这个:

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(顺便说一句,不应该从self.speed setter结果中设置speed对该setter进行无限递归调用?)而是引用私有支持浮点值?然后,也许你能够实例化GKAgent2dSubClass类型的对象(但是你已经命名了那个子类)并使它有效。