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

时间:2016-03-08 23:14:28

标签: swift cocos2d-iphone spritebuilder

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

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

Tile类有m_background类型的CCSprite9Slicem_label类型的CCLabelTTF,两者都映射到private weak var Tile Swift类中的属性。

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

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

Tile.setValueTile类中定义为:

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

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

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

private var m_label: CCLabelTTF!;

然后代码执行正常,加载MainScene时标签的值会更新。然而,当我尝试导航离开MainScene时出现错误malloc: *** error for object 0x7a9f3200: pointer being freed was not allocated现在应用程序崩溃了,这听起来像是在解析现在拥有的Tile类中的强大属性时出现问题由MainScene

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

此处参考的是MainSceneTile类的完整内容:

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!;
}

1 个答案:

答案 0 :(得分:0)

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

internal weak var m_label: CCLabelTTF!;

而不是

private weak var m_label: CCLabelTTF!;

我不确定为什么private在某些情况下会起作用,但在其他情况下却不起作用,我无法正确地封装这些数据,这是一种耻辱。我想这可能是由于SpriteBuilder库中的错误或者由于Swift语言造成的限制。