【问题标题】:Accessing Instance Method from other class in Obj-C [closed]从 Objc 中的另一个类访问实例方法 [关闭]
【发布时间】:2013-01-05 05:50:13
【问题描述】:

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

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

例如: 我有我的主要gameLayer 课程和hudLayer 课程。 hudLayer 类正在导入并在 gameLayer 类中实例化。但是,我需要能够访问和操作在 hudLayer 类中加载的 sprites gameLayer 类。

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

+[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!");
    }

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

感谢您的帮助。

【问题讨论】:

    标签: ios objective-c xcode methods levelhelper


    【解决方案1】:

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

    在我看来,它好像就在这里:

       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; 
    

    我不确定这是否是阅读我的答案后的修改。不过这里还有一些想法。

    首先,您能否整理一下您的命名约定。类应以大写字母开头。

    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

    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。始终如一。想想一个类实际上为你做什么

    【讨论】:

    • 在我的 hudLayer.mm 的 init 方法中,我调用 lh = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];在 .h 我有 LevelHelperLoader* lh;
    • 感谢您的帮助,我将根据您的建议进行更改,看看它是如何工作的。在我的 GameLayer.m 中,我根据角色位置移动视图,因此如果我在这一层上有 hud,则 hud 将被移出视图。为了解决这个问题,我为游戏中的资产创建了单独的类,这些资产应始终显示在屏幕上。但是,当使用 GameLayer.m 加载的精灵发生某些事情时,我需要将更改应用于加载在 HudLayer.m 中的精灵。所以为了做到这一点,我需要 GameLayer 能够访问这些精灵,然后在 HudLayer 中更改它们。
    • 我也有使用 NSUserDefaults 更改布尔值并使用 GameLayer.h 保存它的想法,然后让 HudLayer 不断加载并检查布尔值,但我不确定这对我的来说是否非常有效保存知识的 NSUserDefaults 可能会占用资源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 2012-12-18
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 2014-11-05
    相关资源
    最近更新 更多