2014-09-29 55 views
1

我使用Objective-C在SpriteKit中创建一个游戏。我正在尝试为游戏中使用的屏幕生成块。SpriteKit:NSInvalidArgumentException - 试图添加一个已经拥有父代的SKNode

我发现了一个应用程序崩溃在启动时:

*** 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:

在添加例外Br eakpoint,它显示导致问题的线路是self addChild:block线

+0

添加异常断点。发布generateboard方法。 boardRows不得包含两次相同的节点 – LearnCocos2D 2014-09-29 08:11:58

+0

什么是异常断点?现在添加generateBoard方法 – 2014-09-29 08:27:30

+0

https://developer.apple.com/library/ios/recipes/xcode_help-breakpoint_navigator/articles/adding_an_exception_breakpoint.html – LearnCocos2D 2014-09-30 09:32:43

回答

0

答案很简单,基本上我有一些预先配置的模块以使代数更容易,但是在这样做时,调用self addChild:block实际上是试图将同一个块(具有相同的内存地址)一次添加到2个位置,因此导致应用程序崩溃。

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

相关问题