Reputation: 780
I'm using Cocos2d and I can not access properties of an object from another one. Here I just want to get the hitpoints of a ship form a scene. It fails and returns an error : uncaught exception 'NSInvalidArgumentException', reason: '-[CCSprite hitpoints]: unrecognized selector...
As hitpoints is declared in the interface of the class Ship I can't figure out why. The only thing I understand is that it's a inhéritance issue.
Let's show some code :
Ship.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"
@interface Ship : CCSprite {
int hitpoints;
}
@property (nonatomic, assign) int hitpoints;
- (id)init;
@end
Then Ship.m
#import "Ship.h"
@implementation Ship
@synthesize hitpoints;
- (id)init
{
hitpoints = 3;
self = [CCSprite spriteWithImageNamed:@"ship.png"];
return self;
}
@end
In the Scene.m
#import "Ship.h"
@implementation Scene
{
Ship *_player;
}
- (id)init
{
_player = [[Ship alloc] init];
[self addChild:_player];
// ERROR HERE
NSLog(@"%s = %d", "_player hp", [_player hitpoints]);
}
Thank you.
Upvotes: 0
Views: 156
Reputation: 100622
This:
- (id)init
Means "a method that returns any kind of object, which is called init
".
This:
self = [CCSprite spriteWithImageNamed:@"ship.png"];
Means "create an instance of CCSprite
". You then return that instance.
So _player
ends up being an instance of CCSprite
. CCSprite
does not implement hitpoints
so the exception is raised.
What are you actually trying to achieve? A subclass of CCSprite
? trojanfoe has covered how to write a proper init
for that. Things I think you need to know:
init
being able to return any kind of class — it's a useful feature, not a misfeature.Upvotes: 1
Reputation: 122391
I suspect the issue is with your init
method; you shouldn't be accessing properties until the object is initialised and you should be calling [super initWith...]
instead of the class creation method.
I would suggest the following changes:
Ship.h:
@interface Ship : CCSprite
@property (nonatomic, assign) int hitpoints;
@end
Ship.m:
#import "Ship.h"
@implementation Ship
@synthesize hitpoints;
- (id)init
{
self = [super initWithImageNamed:@"ship.png"];
if (self) {
self.hitpoints = 3;
}
return self;
}
@end
Always use object.property
when referencing a property, even when object == self
.
Upvotes: 2