Have you tried stepping through your code in the debugger to find exactly which line causes the crash?
To me it looks as if it is here:
LevelHelperLoader* lh;
finishScreen = [lh spriteWithUniqueName:@"finishScreen"];
You have declared 1h, but you haven't created it. So you are sending a message to a non-existent object.
At very least, something like
LevelHelperLoader* lh = [[LevelHelperLoader alloc] init];
would help.
A cursory glance at the documentation adds more detail:
LevelHelperLoader* loader = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
In the docs, this is an instance variable - which suggests that hudLoader should be an instance method, not a class method:
- (LevelHelperLoader*) hudLoader;
and you should create your LevelHelperLoader* instance in your hudLoader initialiser.
update
You say in your comment:
inside of my init method for hudLayer.mm i call
lh = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
and in the .h i have
LevelHelperLoader* lh;
I am not sure if this is modifications since reading my answer or not. However here are some more thoughts.
Firstly can you sort out your naming conventions. Classes should start with Capitals.
HudLayer.h
Let's declare this lh
instance variable as a property in your @interface and improve it's name:
@property (strong) LevelHelperLoader* levelHelper
HudLayer.mm
Allow it to be auto-synthesized or synthesize in your @implementation as:
@synthesize levelHelper = _levelHelper;
Then in your init method
_levelHelper = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
and hudLoader
becomes
-(LevelHelperLoader*)hudLoader
{
finishScreen = [self.levelHelper spriteWithUniqueName:@"finishScreen"];
return self.levelHelper;
}
but then ask yourself, what is -hudLoader
actually doing? The line that assigns to finishscreen
? Is finishscreen
an iVar? Do you need it? Perhaps not. Aside from that, all -hudLoader
is doing is returning your already-created instance of LevelHelperLoader. Now that your iVar is a property you can access this from gameLayer using dot-notation property syntax, and remove hudLoader
altogether:
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!");
}
This makes me wonder whether you need a hudLayer class at all (maybe it is doing other useful work)... it looks as if you can get at your levelHelper directly from gameLayer.
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!");
}
To conclude, I am not suggesting you follow this code line-for-line because I have no idea the broader context of your project. But you do need to sort out your confusion between classes and instances, allocation, instantiation, local vs instance variables. Please take care with naming conventions so that you know when you are sending a message to a Class or an instance of that class, and you know when you are addressing an iVar _directly or via a @property (eg self.property). Be consistent. And think about what a class is actually doing for you.