您是否尝试过在调试器中单步执行您的代码以准确找出导致崩溃的行?
对我来说,它看起来好像在这里:
LevelHelperLoader* lh;
finishScreen = [lh spriteWithUniqueName:@"finishScreen"];
您已声明1h,但尚未创建它。因此,您正在向不存在的对象发送消息。
至少,像
LevelHelperLoader* lh = [[LevelHelperLoader alloc] init];
有助于。
粗略浏览一下文档会增加更多细节:
LevelHelperLoader* loader = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
在文档中,这是一个实例变量——这表明 hudLoader 应该是一个实例方法,而不是一个类方法:
- (LevelHelperLoader*) hudLoader;
你应该在你的 hudLoader 初始化器中创建你的 LevelHelperLoader* 实例。
更新
你在评论中说:
在我调用的 hudLayer.mm 的 init 方法中
lh = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
并且在 .hi 中有
LevelHelperLoader* lh;
我不确定这是否是阅读我的答案后的修改。然而,这里还有一些想法。
首先,您能否理清您的命名约定。课程应以大写字母开头。
HudLayer.h
让我们将此lh
实例变量声明为 @interface 中的属性并改进它的名称:
@property (strong) LevelHelperLoader* levelHelper
HudLayer.mm
允许它在您的@implementation 中自动合成或合成:
@synthesize levelHelper = _levelHelper;
然后在你的 init 方法中
_levelHelper = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
并hudLoader
成为
-(LevelHelperLoader*)hudLoader
{
finishScreen = [self.levelHelper spriteWithUniqueName:@"finishScreen"];
return self.levelHelper;
}
但然后问问自己,-hudLoader
实际上在做什么?分配给的行finishscreen
?是finishscreen
iVar 吗?你需要它吗?也许不是。除此之外,-hudLoader
所做的一切就是返回您已经创建的 LevelHelperLoader 实例。现在您的 iVar 是一个属性,您可以使用点符号属性语法从 gameLayer 访问它,并hudLoader
完全删除:
游戏层.h
@interface
@property (strong) Hudlayer* hudLayer;
@end
游戏层.m
-(id) init {
_hudLayer = [[Hudlayer alloc] init];
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [self.hudLayer.levelHelper spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
这让我想知道你是否需要一个 hudLayer 类(也许它正在做其他有用的工作)......看起来你可以直接从 gameLayer 获得你的 levelHelper。
游戏层.h
@interface
@property (strong) LevelHelperLoader* levelHelper;
@end
游戏层.m
-(id) init {
_levelHelper = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [self.levelHelper spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
最后,我不建议您逐行遵循此代码,因为我不知道您项目的更广泛背景。但是您确实需要理清类和实例、分配、实例化、本地变量与实例变量之间的混淆。请注意命名约定,以便您知道何时向类或该类的实例发送消息,并且知道何时直接或通过@property(例如self.property)寻址iVar。始终如一。想想一堂课实际上为你做了什么。