I have cocos2d project with custom CCSprite subclass:
MyCustomSprite.h:
#import "cocos2d.h"
@interface MyCustomSprite : CCSprite
@end
MyCustomSprite.m:
#import "MyCustomSprite.h"
@implementation MyCustomSprite
- (id)init
{
self = [super initWithFile:@"index.png"];
return self;
}
@end
For some strange reason, this code will crash with "EXC_BAD_ACCESS".
But in spite of this, if i init super as ususal and then write code from CCSprite's initWithFile and initWithTexture, it will work fine:
self = [super init];
if (self) {
// Code from CCSprite.m - initWithFile
CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage: @"index.png"];
CGRect rect = CGRectZero;
rect.size = texture.contentSize;
// Code from CCSprite.m - iniWithTexture
[self setTexture:texture];
[self setTextureRect:rect];
return self;
}
What's the reason that the first example crashes, and second not and what's the difference between them?
Thanks for your answers!
Ok, the reason is bad CCSprite design. If we look to CCSprite.h, we can find:
-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect
{
NSAssert(texture!=nil, @"Invalid texture for sprite");
// IMPORTANT: [self init] and not [super init];
if( (self = [self init]) )
}
And thats the reason. Instead of [super init]
this method calls [self init]
, and creates recursion ([self init]-[super InitWithFile:]-[self initWithTexture]-[self init]-...)
.
.
So, the simplest way to solve this problem - just re-name your init method to something else (for example "initialize") and call it instead of init: [[MyCustomSprite
alloc] initialize]
.