SpriteKit:NSInvalidArgumentException - 尝试添加已具有父级的SKNode

时间:2014-09-29 06:47:33

标签: objective-c sprite-kit skspritenode

我使用Objective-C在SpriteKit中创建游戏。我正在尝试为游戏中的屏幕生成块。

我在启动时遇到应用程序崩溃:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent: <SKSpriteNode> name:'Block-0.000000-440.000000' texture:['nil'] position:{0, 440} size:{64, 64} rotation:0.00'
*** First throw call stack:
(
    0   CoreFoundation                      0x00891df6 __exceptionPreprocess + 182
    1   libobjc.A.dylib                     0x0051ba97 objc_exception_throw + 44
    2   CoreFoundation                      0x00891d1d +[NSException raise:format:] + 141
    3   SpriteKit                           0x00e8c94c -[SKNode addChild:] + 119
    4   Hidden Route                        0x0003b3c1 -[GameScene didMoveToView:] + 2417
    5   SpriteKit                           0x00e6031b -[SKScene _didMoveToView:] + 97
    6   SpriteKit                           0x00e7b157 -[SKView presentScene:] + 283
    7   Hidden Route                        0x00039e9e -[GameViewController viewDidLoad] + 526
    8   UIKit                               0x0115ad54 -[UIViewController loadViewIfRequired] + 771
    9   UIKit                               0x0115b045 -[UIViewController view] + 35
    10  UIKit                               0x0105f477 -[UIWindow handleStatusBarChangeFromHeight:toHeight:] + 879
    11  UIKit                               0x0106252d +[UIWindow _noteStatusBarHeightChanged:oldHeight:forAutolayoutRootViewsOnly:] + 273
    12  UIKit                               0x01006ad1 __79-[UIApplication _setStatusBarHidden:animationParameters:changeApplicationFlag:]_block_invoke + 163
    13  UIKit                               0x010862c6 +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 494
    14  UIKit                               0x01086701 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:animations:completion:] + 115
    15  UIKit                               0x0100699e -[UIApplication _setStatusBarHidden:animationParameters:changeApplicationFlag:] + 506
    16  UIKit                               0x01006128 -[UIApplication _updateCurrentStatusBarViewControllerAppearance] + 286
    17  UIKit                               0x0105223a -[UIWindow _updateContextOrderingAndSetLayerHidden:] + 548
    18  UIKit                               0x0105319e -[UIWindow _setHidden:forced:] + 257
    19  UIKit                               0x01053473 -[UIWindow _orderFrontWithoutMakingKey] + 49
    20  UIKit                               0x01061615 -[UIWindow makeKeyAndVisible] + 80
    21  UIKit                               0x00ffecd6 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 3108
    22  UIKit                               0x0100216d -[UIApplication _runWithMainScene:transitionContext:completion:] + 1639
    23  UIKit                               0x0101ad30 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke + 59
    24  UIKit                               0x01000d7f -[UIApplication workspaceDidEndTransaction:] + 155
    25  FrontBoardServices                  0x06f909de __37-[FBSWorkspace clientEndTransaction:]_block_invoke_2 + 71
    26  FrontBoardServices                  0x06f9046f __40-[FBSWorkspace _performDelegateCallOut:]_block_invoke + 54
    27  FrontBoardServices                  0x06fa2425 __31-[FBSSerialQueue performAsync:]_block_invoke + 26
    28  CoreFoundation                      0x007b57a0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 16
    29  CoreFoundation                      0x007ab0b3 __CFRunLoopDoBlocks + 195
    30  CoreFoundation                      0x007aaf0b __CFRunLoopRun + 2715
    31  CoreFoundation                      0x007aa1ab CFRunLoopRunSpecific + 443
    32  CoreFoundation                      0x007a9fdb CFRunLoopRunInMode + 123
    33  UIKit                               0x01000744 -[UIApplication _run] + 571
    34  UIKit                               0x01003e16 UIApplicationMain + 1526
    35  Hidden Route                        0x0003c41d main + 141
    36  libdyld.dylib                       0x02fa0ac9 start + 1
    37  ???                                 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

我查看了堆栈跟踪,发现造成问题的方法是我的didMoveToView:方法,即:

-(void)didMoveToView:(SKView *)view
{
    // ViewDidLoad
    [self initialize];

    /* Setup your scene here
    SKLabelNode *myLabel = [SKLabelNode labelNodeWithFontNamed:@"Arial"];

    myLabel.text = @"Hello, World!";
    myLabel.fontSize = 65;
    myLabel.position = CGPointMake(CGRectGetMidX(self.frame),
                                   CGRectGetMidY(self.frame));
    */
    player = [SKSpriteNode spriteNodeWithColor:[AppDelegate getRandomColor] size:CGSizeMake(40, 40)];
    player.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));

    [self generateBoard];
    [self generateNextAtIndex:kNeed - 3];

    int width = (self.frame.size.width) / [AppDelegate numberOfColumns];
    int height = (self.frame.size.height) / kNeed;


    for (int i = 0; i < boardRows.count; i++)
    {
        Row *current = [boardRows objectAtIndex:i];

        for (int j = 0; j < current.blocks.count; j++)
        {
            Block *block = [current.blocks objectAtIndex:j];

            block.anchorPoint = CGPointMake(0, 1);
            block.position = CGPointMake((j * width), self.frame.size.height - (i * width));
            [block setName:[NSString stringWithFormat:@"Block-%f-%f", block.position.x, block.position.y]];

            NSLog(@"Position for item %i", i);

            block.size = CGSizeMake(width, width);

            [self addChild:block];
        }
    }


    [self addChild:player];
}

我觉得它与self addChild:block行有关,但我无法找到解决方案。如果您需要更多信息,我会在此处发布(只是要求它)

感谢您的帮助

编辑1:

generateBoard方法:

- (void)generateBoard
{
    int rnd = 2;

    int from = rnd;
    int to = 0;

    Row *row = [defaultRows objectAtIndex:rnd];
    [boardRows replaceObjectAtIndex:0 withObject:row];

    for (int i = 2; i < boardRows.count; i++)
    {
        rnd = arc4random() % [AppDelegate numberOfColumns];
        to = rnd;

        Row *rowThis = [defaultRows objectAtIndex:rnd];

        Row *rowBelow = [[Row alloc] initWithSize:CGSizeMake(self.frame.size.width, self.frame.size.height) need:kNeed];

        [rowBelow generateWithPoint:from toPoint:to];

        [boardRows replaceObjectAtIndex:i withObject:rowThis];
        [boardRows replaceObjectAtIndex:i-1 withObject:rowBelow];

        to = from;
        from = rnd;

        // to make it add 2
        i++;
    }
}

编辑2:

在异常断点中添加后,它显示导致问题的行是self addChild:block

1 个答案:

答案 0 :(得分:0)

这个问题的答案非常简单,基本上我有一些预配置的块来简化生成,但是在这样做时,调用self addChild:block实际上是在尝试添加相同的块(具有相同的内存地址)一次进入2个地方,因此崩溃了应用程序。

我刚刚在Block类中添加了一个重复的函数,并开始实现它而不是直接调用块。