0

首先,我使用的是游戏引擎LevelHelper

有谁知道LevelHelper从另一个类访问实例化助手类的正确方法?

例如: 我有我的主gameLayer班和一个hudLayer班。该类hudLayer正在被导入并在gameLayer该类中实例化。但是我需要能够访问和操作在类sprites中加载的类。hudLayergameLayer

我被推荐使用LevelHelper辅助实例方法。所以我在我的 hudLayer 类中创建了实例方法,然后在我的init方法中调用它来加载精灵。我尝试将此方法用作实例方法,但出现错误提示无法识别的选择器

+[hudLayer hudLoader];

如果我尝试将该方法用作类方法,则会出现EXC_BAD_ACCESS错误。

我似乎找不到解决方案。

我的代码:

hudLayer.h:

+(LevelHelperLoader*)hudLoader;

hudLayer.mm :

  +(LevelHelperLoader*)hudLoader
    {
       LevelHelperLoader* lh;
       finishScreen = [lh spriteWithUniqueName:@"finishScreen"];
        return lh;
    }

游戏层.h:

  LHSprite* finishScreen;

游戏层.mm:

#import hudLayer.h

  -(id) init {
       [self retrieveRequiredObjects];

    }

  -(void) retrieveRequiredObjects {
        finishScreen = [[hudLayer  hudLoader] spriteWithUniqueName:@"finishScreen"];
        NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
    }

注意:这段代码只是为了确保我的逻辑和实现是正确的。

任何帮助表示赞赏,谢谢。

4

1 回答 1

2

您是否尝试过在调试器中单步执行您的代码以准确找出导致崩溃的行?

对我来说,它看起来好像在这里:

   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?是finishscreeniVar 吗?你需要它吗?也许不是。除此之外,-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。始终如一。想想一堂课实际上为你了什么。

于 2013-01-22T03:55:11.880 回答