1

我有自定义 CCSprite 子类的 cocos2d 项目:

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

由于某些奇怪的原因,此代码将因“EXC_BAD_ACCESS”而崩溃。

但尽管如此,如果我像往常一样初始化超级,然后从 CCSprite 的 initWithFile 和 initWithTexture 编写代码,它会正常工作:

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;
} 

第一个示例崩溃的原因是什么,第二个示例没有,它们之间有什么区别?

感谢您的回答!

4

2 回答 2

1

好的,原因是糟糕的 CCSprite 设计。如果我们查看 CCSprite.h,我们可以找到:

-(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]) )
}

这就是原因。而不是[super init]这个方法调用[self init],并创建递归([self init]-[super InitWithFile:]-[self initWithTexture]-[self init]-...)

.

因此,解决此问题的最简单方法 - 只需将您的 init 方法重命名为其他名称(例如“initialize”)并调用它而不是 init: [[MyCustomSprite alloc] initialize]

于 2011-09-04T10:05:54.947 回答
0

另一种可能有效的方法是将您的代码替换为以下代码:

- (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;
}

更简单的方法是,如果您使用的是 CCSpriteFrameCache,只需通过

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

希望能帮助别人!

于 2012-02-14T08:09:58.280 回答