类的实例和正确的初始化

时间:2014-06-12 23:22:57

标签: ios sprite-kit swift

我移植了这个项目 - https://gist.github.com/cmezak/8393434并让它工作但我对处理类的实例和正确初始化的差异有疑问。

在GameScene.swift中,我创建了一个带有SKSpriteNode实例的属性,如下所示:

class GameScene: SKScene {
    var nodeToScroll: SKSpriteNode

    init(size: CGSize) {
        nodeToScroll = SKSpriteNode(imageNamed: "image")
        super.init(size: size)
        nodeToScroll.anchorPoint = CGPointMake(0, 0)
        nodeToScroll.position = CGPointMake(0, size.height - nodeToScroll.size.height)
        self.addChild(nodeToScroll)
    }
}

在GameViewController.swift中我有:

var skView = SKView()
var scene = GameScene(size: CGSize())
var scrollView = UIScrollView()

class GameViewController: UIViewController, UIScrollViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        skView = SKView(frame: CGRectMake(0, 0, 1024, 768))
        self.view.addView(skView)

        scene = GameScene(size: skView.bounds.size)
        scene.scaleMode = .AspectFill

        scrollView = UIScrollView(frame: skView.frame)
        scrollView.hidden = true
        scrollView.delegate = self
        self.view.addSubview(scrollView)
        scrollView.contentSize = scene.calculateAccumulatedFrame().size

        skView.addGestureRecognizer(scrollView.panGestureRecognizer)
        skView.presentScene(scene)
    }

就像我说的,这是有效的,但我尝试遵循Swift模式,如

if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
它打破了。所以我的问题是,我应该如何处理需要viewDidLoad之外的场景实例的案例?我认为这将是一个简单的端口,但现在我已经盯着它看了很长时间,我甚至不知道我在做什么。建议?

编辑: 我将viewController编辑为:

var skView: SKView!
var scene: GameScene!
var scrollView: UIScrollView!

class GameViewController: UIViewController, UIScrollViewDelegate {

override func viewDidLoad() {
    super.viewDidLoad()

    if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
        // Configure the view.
        let skView = self.view as SKView
        skView.showsFPS = true
        skView.showsNodeCount = true

        /* Sprite Kit applies additional optimizations to improve rendering performance */
        skView.ignoresSiblingOrder = true
        self.view.addSubview(skView)
        /* Set the scale mode to scale to fit the window */
        scene.size = skView.bounds.size

        scene.scaleMode = .AspectFill

        scrollView = UIScrollView(frame: skView.frame)
        scrollView.hidden = true
        scrollView.delegate = self
        self.view.addSubview(scrollView)
        scrollView.contentSize = scene.calculateAccumulatedFrame().size


        skView.addGestureRecognizer(scrollView.panGestureRecognizer)
        skView.presentScene(scene)
    }

}

我没有收到任何警告或错误但是当我运行它时,我得到了致命错误:使用未实现的初始化程序&#init;编码器:'上课' SwiftScrollKit.GameScene'"

然后我添加了

init(coder aDecoder: NSCoder!) {
    super.init(coder: aDecoder)
}

到GameScene课程,现在不能将自己添加为子视图' - hooboy ......我不知道为什么这会让我陷入这样的循环,但我一定不能抓住这里可能正好在我鼻子底下的东西。

1 个答案:

答案 0 :(得分:3)

在您更正实例变量的范围之前,您将陷入困境。在您链接到的要点中,他们已在您@implementation { ... }的{​​{1}}块内声明,但此处他们已完全在课堂外宣布,这意味着他们全球化在适用范围。

ViewController内,您在该方法的范围内重新定义viewDidLoadscene,在您进行配置时隐藏全局值。这些局部变量然后在skView结束时被取消分配,因此您无法访问您在那里设置的任何内容。 (它们可能存在于视图层次结构中,但是您的全局变量无法工作。)

您希望在班级中移动这些全局变量,然后使用viewDidLoad访问它们,这样您就不会将它们与局部变量混合在一起。然后,课程中的其他方法也可以访问您在self.variableName中设置的内容:

viewDidLoad

最后,"不能将自己添加为子视图"错误正在发生,因为:

class GameViewController: UIViewController, UIScrollViewDelegate {
    var skView: SKView!
    var scene: GameScene!
    var scrollView: UIScrollView!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.scene = // load the scene
        self.skView = SKView(frame: CGRectMake(0.0, 0.0, 1024.0, 768.0))
        self.view.addSubview(self.skView)
        // etc
    }
}