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;
    }

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

注:このコードは、私のロジックとこれの実装が正しいことを確認するためのものです。

どんな助けでも大歓迎です、ありがとう。

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完全に削除できます。

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

結論として、私はあなたのプロジェクトのより広い文脈を知らないので、このコードを一行一行たどることを勧めているわけではありません。ただし、クラスとインスタンス、割り当て、インスタンス化、ローカル変数とインスタンス変数の間の混乱を整理する必要がありますクラスまたはそのクラスのインスタンスにメッセージを送信するタイミングと、iVar を _directly または @property (例: self.property) 経由でアドレス指定するタイミングがわかるように、命名規則に注意してください。一貫性を保ちます。そして、クラスが実際にあなたのために何をしているかを考えてみてください。

于 2013-01-22T03:55:11.880 に答える