Cocos2d: CCSprite initWithFile in CCSprite subclass crashes

喜你入骨 提交于 2019-12-08 08:36:49

问题


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!


回答1:


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].




回答2:


Another approach that may work is just replace your code by this one:

- (id)init
{
    self = [super init];
    if (self != nil)
    {
        CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage:@"my_image_name.png"];
        CGRect rect = CGRectZero;
        if (texture != nil)
        {
            rect.size = texture.contentSize;
        }
        [self setDisplayFrame:[CCSpriteFrame frameWithTexture:texture rect:rect]];
    }
    return self;
}

And a simpler way, if you are using CCSpriteFrameCache, would be just setting the display frame by

[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"my_image_name.png"]

Hope to help somebody!



来源:https://stackoverflow.com/questions/7293851/cocos2d-ccsprite-initwithfile-in-ccsprite-subclass-crashes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!