SpriteKit: NSInvalidArgumentException - 试图添加一个已经有父节点的 SKNode
Posted
技术标签:
【中文标题】SpriteKit: NSInvalidArgumentException - 试图添加一个已经有父节点的 SKNode【英文标题】:SpriteKit: NSInvalidArgumentException - Attempted to add a SKNode which already has parent 【发布时间】:2014-09-29 06:47:33 【问题描述】:我正在使用 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
行
【问题讨论】:
添加异常断点。发布生成板方法。 boardRows 不能两次包含相同的节点 什么是异常断点?现在添加 generateBoard 方法 developer.apple.com/library/ios/recipes/… 【参考方案1】:这个问题的答案很简单,基本上我有一些预先配置的块来简化生成,但是在这样做时,调用self addChild:block
实际上是试图将相同的块(具有相同的内存地址)添加到 2一次放置,因此导致应用程序崩溃。
我刚刚在我的 Block 类中添加了一个重复的函数并开始实现它,而不是直接调用该块。
【讨论】:
以上是关于SpriteKit: NSInvalidArgumentException - 试图添加一个已经有父节点的 SKNode的主要内容,如果未能解决你的问题,请参考以下文章