Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift Code Connections nil reference and deallocation issues #1606

Open
Choc13 opened this issue Mar 8, 2016 · 0 comments
Open

Swift Code Connections nil reference and deallocation issues #1606

Choc13 opened this issue Mar 8, 2016 · 0 comments

Comments

@Choc13
Copy link

Choc13 commented Mar 8, 2016

Hi,

I am using Swift (XCode 7.2.1) and SpriteBuilder (1.4.9) to create a game. However I am having some problems with the creating code connections between CCB files and Swift classes. I followed the tutorials online and added a doc root var code connection name in SpriteBuilder and then set up the corresponding property in the class as a private weak var m_myVar: MyClass!. However whenever I try and access the property I get a nil reference. If I remove the weak attribute from the code connection then I can access the property, but I receive deallocation issues when the scene is detroyed, e.g. navigating to a new scene using the CCDirector.shareDirector().replaceScene() method.

In my specific case I have a MainScene in SpriteBuilder with the following node hierarchy within it: CCNode -> CCNodeGradient -> Tile. Where Tile a subclass of CCNode defined in a different CCB file and has the doc root var code connection name of m_levelLabel, which maps to the private weak var m_levelLabel: Tile! property of the MainScene class.

The Tile class has 2 properties m_background of type CCSprite9Slice and m_label of type CCLabelTTF, both of which are mapped to private weak var properties in the Tile Swift class.

When the MainScene loads I attempt to set some properties on the m_levelLabel using the following code:

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

and Tile.setValue is defined in the Tile class as:

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

But when the setValue method executes the m_label property is nil and so the fatal error: unexpectedly found nil while unwrapping an Optional value occurs. This is odd as clearly my code connections in the MainScene class have worked fine as I was able to call m_levelLabel.setValue.

Interestingly if I change the properties in the Tile class to be defined as strong references like:

private var m_label: CCLabelTTF!;

Then the code executes fine and the value of the label is updated when the MainScene loads. However the app now crashes when I try and navigate away from the MainScene with the error malloc: *** error for object 0x7a9f3200: pointer being freed was not allocated which sounds like there is a problem when destroying the, now, strong properties in the Tile class owned by the MainScene.

What could be going on here? What is the correct way to define code connections in Swift? Note I receive no warnings in the console about missing code connection properties.

For reference here is the MainScene and Tile class in their entirety:

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!;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant