SpriteBuilder Swift 代码连接无引用和释放问题

SpriteBuilder Swift code connections nil reference and deallocation issues

我正在使用 Swift (XCode 7.2.1) 和 SpriteBuilder (1.4.9) 创建游戏。但是,我在 CCB 文件和 Swift classes 之间创建代码连接时遇到了一些问题。我按照网上的教程在SpriteBuilder中添加了一个doc root var code connection name,然后在class中设置了相应的属性作为private weak var m_myVar: MyClass!。但是,每当我尝试访问 属性 时,我都会得到一个 nil 引用。如果我从代码连接中删除 weak 属性,那么我可以访问 属性,但是当场景被销毁时,我会收到重新分配问题,例如使用 CCDirector.shareDirector().replaceScene() 方法导航到新场景。

在我的特定情况下,我在 SpriteBuilder 中有一个 MainScene,其中包含以下节点层次结构:CCNode -> CCNodeGradient -> Tile。其中 Tile CCNode 的子 class 在不同的 CCB 文件中定义并且具有 doc root var 代码连接名称 m_levelLabel,它映射到 private weak var m_levelLabel: Tile! 属性 的 MainScene class。

Tile class 有 2 个 CCSprite9Slice 类型的属性 m_backgroundCCLabelTTF 类型的 m_label,它们都是映射的Tile Swift class 中的 private weak var 属性。

MainScene 加载时,我尝试使用以下代码在 m_levelLabel 上设置一些属性:

internal func didLoadFromCCB() {
    m_levelLabel.setValue("2");
}

Tile.setValueTileclass中定义为:

internal func setValue(value: String) {
    m_label.string = value;
}

但是当 setValue 方法执行时 m_label 属性 是 nil 所以 fatal error: unexpectedly found nil while unwrapping an Optional value 发生了。这很奇怪,因为我在 MainScene class 中的代码连接工作正常,因为我能够调用 m_levelLabel.setValue.

有趣的是,如果我将 Tile class 中的属性更改为定义为强引用,例如:

private var m_label: CCLabelTTF!;

然后代码执行正常,标签的值在 MainScene 加载时更新。但是,当我尝试离开 MainScene 并出现错误 malloc: *** error for object 0x7a9f3200: pointer being freed was not allocated 时,应用程序现在崩溃了,这听起来像是在破坏 Tile [=] 中的强大属性时出现问题82=] 归 MainScene.

所有

这里可能发生了什么?在 Swift 中定义代码连接的正确方法是什么?请注意,我在控制台中没有收到有关缺少代码连接属性的警告。

这里是 MainSceneTile class 的完整参考:

Main.swift

import Foundation

internal class MainScene: CCScene {

    internal func didLoadFromCCB() {
        m_levelLabel.setValue("1");
        m_progressLabel.setValue("0%");
    }

    internal func play() {
        let gameplayScene: CCScene = CCBReader.loadAsScene("Gameplay/GameplayScene");
        CCDirector.sharedDirector().replaceScene(gameplayScene);
    }

    internal func levelSelection() {
        print("Pressed level selection");
    }

    internal func progress() {
        print("Pressed progress button");
    }

    private weak var m_playButton: CCButton!;
    private weak var m_levelSelectionButton: CCButton!;
    private weak var m_progressButton: CCButton!;
    private weak var m_levelLabel: Tile!;
    private weak var m_progressLabel: Tile!;
}

Tile.swift

import Foundation

internal class Tile : CCNode {

    internal var value: String? {
        return m_label?.string;
    }

    internal func setValue(value: String) {
        m_label.string = value;
    }

    private weak var m_label: CCLabelTTF!;
    private weak var m_background: CCSprite9Slice!;
}

所以事实证明,要使代码连接始终有效,它们必须具有 internal 可访问性而不是 private。例如。

internal weak var m_label: CCLabelTTF!;

而不是

private weak var m_label: CCLabelTTF!;

我不确定为什么 private 在某些情况下有效,但在其他情况下却无效,很遗憾我无法正确封装这些数据。我想这要么是由于 SpriteBuilder 库中的错误,要么是由于 Swift 语言的限制。