SKNode子类中的__stack_chk_fail

时间:2014-10-03 10:07:03

标签: ios objective-c memory-leaks sprite-kit sknode

我试图为将要重复调用的节点创建一个SKNode子类,每次都有用户交互,然后是破坏/爆炸效果。但是,每当我尝试运行代码时,都会收到SIGABRT错误。与调试终端中的___stack_chk_fail有关。

此外,在检查器中,当SIGABRT的代码中断时,所有这些属性都显示为nil

这是我的SKNode子类的.m:

#import "CandyNode.h"

static const int MAX_VELOCITY = 20;
static const int MIN_VELOCITY = 2;

@implementation CandyNode

- (instancetype)init {
    self = [super init];
    if (self == [super init])
    {
        _spriteType = arc4random()%4+1;
        NSString* imageRand = [NSString stringWithFormat:@"Sprite %i", _spriteType];

        _background = [SKSpriteNode spriteNodeWithImageNamed:imageRand];
        _background.name = @"Main";
        _background.zPosition = 3;
        [self addChild:_background];

        _burst1 = [SKSpriteNode spriteNodeWithImageNamed:[NSString stringWithFormat:@"S%dB%d",_spriteType,1]];
        _burst2 = [SKSpriteNode spriteNodeWithImageNamed:[NSString stringWithFormat:@"S%dB%d",_spriteType,2]];
        _burst3 = [SKSpriteNode spriteNodeWithImageNamed:[NSString stringWithFormat:@"S%dB%d",_spriteType,3]];

        _burst1.name = @"Burst #1";
        _burst2.name = @"Burst #2";
        _burst3.name = @"Burst #3";

        [_background setHidden:NO];

        [_burst1 setHidden:YES];
        [_burst2 setHidden:YES];
        [_burst3 setHidden:YES];

        [self addChild:_burst1];
        [self addChild:_burst2];
        [self addChild:_burst3];

        double burstAngle[3];
        int offsetAngle = 240;
        double burstDisplacement[3];
        CGVector burstVector[3];

        CGFloat x, y;
        for (int i = 0; i<=3; i++){
            burstAngle[i] = (arc4random()%60+120*i+offsetAngle)*3.1415/180;
            burstDisplacement[i] = arc4random()%(MAX_VELOCITY-MIN_VELOCITY)+ MIN_VELOCITY;
            x = burstDisplacement[i]*cos(burstAngle[i]);
            y = burstDisplacement[i]*sin(burstAngle[i]);
            burstVector[i] = CGVectorMake(x, y);
        }

        _explode1 = [SKAction sequence:@[[SKAction fadeInWithDuration:0],
                                         [SKAction moveBy:burstVector[0] duration:.5],
                                         [SKAction fadeOutWithDuration:.2]]];
        _explode2 = [SKAction sequence:@[[SKAction fadeInWithDuration:0],
                                         [SKAction moveBy:burstVector[1] duration:.5],
                                         [SKAction fadeOutWithDuration:.2]]];
        _explode3 = [SKAction sequence:@[[SKAction fadeInWithDuration:0],
                                         [SKAction moveBy:burstVector[2] duration:.5],
                                         [SKAction fadeOutWithDuration:.2]]];

    }
    return self;

}

·H:

#import <SpriteKit/SpriteKit.h>
@interface CandyNode : SKNode

//-(id)initWithImageNumber:(int)spriteType;
//-(void)explodeCandy;

@property (nonatomic) SKSpriteNode *background;
@property (nonatomic) SKSpriteNode *burst1;
@property (nonatomic) SKSpriteNode *burst2;
@property (nonatomic) SKSpriteNode *burst3;

@property (nonatomic) SKAction *explode1;
@property (nonatomic) SKAction *explode2;
@property (nonatomic) SKAction *explode3;

@property (nonatomic) int spriteType;


@end

并且在主要的SKScene中调用它:_NodeA = [CandyNode new];,_NodeA在该类的标题中定义为@property (nonatomic) CandyNode *NodeA;

我的问题显然是如何让这个工作,或者如果我对如何使用子类和SpriteKit有一个可怕的误解,我怎么能以不同的方式做到这一点?

1 个答案:

答案 0 :(得分:2)

您正在调用init两次:

self = [super init];
if (self == [super init])

第一个正确分配给self,第二个创建一个实例,将它与self进行比较,然后抛弃新实例。

解决此问题:

self = [super init];
if (self)

<强>更新

您声明一个包含3个元素的数组:

double burstAngle[3];

然后枚举数组,范围为0到3(循环运行四次):

for (int i = 0; i<=3; i++){

当i为3时,您的索引超出范围,数组索引从零开始。

修复如下:

for (int i = 0; i < 3; i++){