我正在使用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
类型的CCSprite9Slice
和m_label
类型的CCLabelTTF
,两者都映射到private weak var
Tile
Swift类中的属性。
当MainScene
加载时,我尝试使用以下代码在m_levelLabel
上设置一些属性:
internal func didLoadFromCCB() {
m_levelLabel.setValue("2");
}
和Tile.setValue
在Tile
类中定义为:
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中定义代码连接的正确方法是什么?注意我在控制台中没有收到有关缺少代码连接属性的警告。
此处参考的是MainScene
和Tile
类的完整内容:
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!;
}
答案 0 :(得分:0)
事实证明,为了使代码连接始终有效,它们必须具有internal
可访问性而不是private
。例如。
internal weak var m_label: CCLabelTTF!;
而不是
private weak var m_label: CCLabelTTF!;
我不确定为什么private
在某些情况下会起作用,但在其他情况下却不起作用,我无法正确地封装这些数据,这是一种耻辱。我想这可能是由于SpriteBuilder库中的错误或者由于Swift语言造成的限制。