从Obj-C中的其他类访问实例方法

时间:2013-01-22 03:28:08

标签: ios objective-c xcode methods levelhelper

首先,我正在使用游戏引擎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!");
    }

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

感谢任何帮助,谢谢。

1 个答案:

答案 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。始终如一。并考虑一下班级实际为你做什么