首先,我正在使用游戏引擎LevelHelper
。
是否有人知道从另一个类访问实例化LevelHelper
帮助程序类的正确方法?
例如:
我有我的主要gameLayer
课程和hudLayer
课程。正在导入hudLayer
类并在gameLayer
类中实例化。但是,我需要能够访问和操作sprites
类中加载hudLayer
类的gameLayer
。
我被建议使用LevelHelper
帮助器实例方法。所以我在我的hudLayer类中创建了实例方法,然后在我的init
方法中调用它来加载sprite。我尝试使用此方法作为实例方法,我得到一个错误说无法识别的选择器
+[hudLayer hudLoader];
如果我尝试将该方法用作类方法,则会出现EXC_BAD_ACCESS
错误。
我似乎无法找到解决方案。
我的代码:
hudLayer.h:
+(LevelHelperLoader*)hudLoader;
hudLayer.mm:
+(LevelHelperLoader*)hudLoader
{
LevelHelperLoader* lh;
finishScreen = [lh spriteWithUniqueName:@"finishScreen"];
return lh;
}
gameLayer.h:
LHSprite* finishScreen;
gameLayer.mm:
#import hudLayer.h
-(id) init {
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [[hudLayer hudLoader] spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
注意:此代码只是为了确保我的逻辑和实现是正确的。
感谢任何帮助,谢谢。
答案 0 :(得分:2)
您是否尝试单步执行调试器中的代码以确切地找到导致崩溃的行?
对我来说,它看起来好像在这里:
LevelHelperLoader* lh;
finishScreen = [lh spriteWithUniqueName:@"finishScreen"];
您已宣布 1h,但您尚未创建它。所以你要向一个不存在的对象发送一条消息。
至少,像是
LevelHelperLoader* lh = [[LevelHelperLoader alloc] init];
会有所帮助。
粗略地看一眼documentation会增加更多细节:
LevelHelperLoader* loader = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
在文档中,这是一个实例变量 - 这表明hudLoader应该是一个实例方法,而不是一个类方法:
- (LevelHelperLoader*) hudLoader;
您应该在hudLoader初始化程序中创建LevelHelperLoader *实例。
<强>更新强>
你在评论中说:
在我的hudLayer.mm的init方法中,我打电话给
lh = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
在.h我有
LevelHelperLoader* lh;
自从阅读我的答案以来,我不确定这是否是修改。不过这里还有一些想法。
首先,您可以理清您的命名约定。课程应该从Capitals开始。
<强> 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是一个属性,你可以使用dot-notation属性语法从gameLayer访问它,并完全删除hudLoader
:
<强> GameLayer.h 强>
@interface
@property (strong) Hudlayer* hudLayer;
@end
<强> GameLayer.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。
<强> GameLayer.h 强>
@interface
@property (strong) LevelHelperLoader* levelHelper;
@end
<强> GameLayer.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。始终如一。并考虑一下班级实际为你做什么 。