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