应用程序不断崩溃,终止应用程序由于未捕获的异常'NSInvalidArgumentException'

问题描述:

我正在创建一个游戏,随机物体落在随机的地方,并有一个固定的y轴的球,并继续沿x轴移动,它必须移动投掷物体,我试图计算得分和我做这件事的方式是我创建了一个物理对象,它与球的位置在同一个Y轴上,当对象碰撞时,得分函数应该被调用并将分数增加1,但由于某种原因,应用程序不断崩溃,并且它给了我这个错误。应用程序不断崩溃,终止应用程序由于未捕获的异常'NSInvalidArgumentException'

2015-07-13 01:23:17.242 WalkRun[26792:3773366] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent: <SKSpriteNode> name:'(null)' texture:[<SKTexture> 'shortwall' (60 x 60)] position:{30, 768} size:{60, 60} rotation:0.00' 
*** First throw call stack: 
(
    0 CoreFoundation      0x00000001073c33f5 __exceptionPreprocess + 165 
    1 libobjc.A.dylib      0x00000001092eabb7 objc_exception_throw + 45 
    2 CoreFoundation      0x00000001073c332d +[NSException raise:format:] + 205 
    3 SpriteKit       0x0000000107ebfaf6 -[SKNode addChild:] + 111 
    4 WalkRun        0x00000001071c8c44 _TFC7WalkRun9PlayScene10leftObjectfS0_FT_T_ + 2868 
    5 WalkRun        0x00000001071c7ddc _TFC7WalkRun9PlayScene10randObjectfS0_FT_T_ + 236 
    6 WalkRun        0x00000001071c8102 _TToFC7WalkRun9PlayScene10randObjectfS0_FT_T_ + 34 
    7 Foundation       0x0000000107a39fd4 __NSFireTimer + 83 
    8 CoreFoundation      0x000000010732b4e4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20 
    9 CoreFoundation      0x000000010732b0a5 __CFRunLoopDoTimer + 1045 
    10 CoreFoundation      0x00000001072ee3dd __CFRunLoopRun + 1901 
    11 CoreFoundation      0x00000001072eda06 CFRunLoopRunSpecific + 470 
    12 GraphicsServices     0x000000010e7569f0 GSEventRunModal + 161 
    13 UIKit        0x0000000108046550 UIApplicationMain + 1282 
    14 WalkRun        0x00000001071d54ce top_level_code + 78 
    15 WalkRun        0x00000001071d550a main + 42 
    16 libdyld.dylib      0x0000000109ad9145 start + 1 
) 
libc++abi.dylib: terminating with uncaught exception of type NSException 

,这是我的代码:

// 
// PlayScene.swift 
// WalkRun 
// 
// Created by naeim on 7/10/15. 
// Copyright (c) 2015 naeim. All rights reserved. 
// 

import Foundation 
import SpriteKit 

class PlayScene: SKScene, SKPhysicsContactDelegate{ 

    var ball = SKSpriteNode(imageNamed: "ball") 
    var wall = SKNode() 
    var wallRight = SKNode() 
    var wallMiddle = SKNode() 
    var ballSpeed = CGFloat() 

    var bigWall = SKSpriteNode(imageNamed: "shortwall") 
    var tallWall = SKSpriteNode(imageNamed: "tallwall") 

    var ballGroup:UInt32 = 1 
    var objectGroup:UInt32 = 2 
    var gapGroup:UInt32 = 3 

    var gameOver = 0 

    var movingObjects = SKNode() 

    var score = 0 
    var scoreLabel = SKLabelNode() 

    override func didMoveToView(view: SKView) { 

     self.physicsWorld.contactDelegate = self 

     backgroundColor = UIColor(hex: 0x80d9ff) 
     self.physicsWorld.gravity = CGVectorMake(-9,0) 

     self.addChild(movingObjects) 

     //creating the ball 
     ball.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinY(self.frame) + self.ball.size.height * 2) 
     ball.physicsBody = SKPhysicsBody(circleOfRadius: self.ball.size.width/2) 
     ball.zPosition = 10 


     //let the ball rotate forever 
     ballSpeed = 3 
     let rotateAction = SKAction.rotateByAngle(ballSpeed, duration: 1) 
     let repeatAction = SKAction.repeatActionForever(rotateAction) 
     ball.runAction(repeatAction) 
     ball.physicsBody?.categoryBitMask = ballGroup 
     ball.physicsBody?.collisionBitMask = objectGroup 
     ball.physicsBody?.contactTestBitMask = objectGroup 

     self.addChild(ball) 

     //creating the wall of the left 
     wall.position = CGPointMake(CGRectGetMinX(self.frame),CGRectGetMinY(self.frame)) 
     wall.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(2, self.frame.size.height * 2.0)) 
     wall.physicsBody?.dynamic = false 
     wall.physicsBody?.categoryBitMask = objectGroup 
     self.addChild(wall) 

     //creating the wall of the right 
     wallRight.position = CGPointMake(CGRectGetMaxX(self.frame), CGRectGetMinY(self.frame)) 
     wallRight.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(2, self.frame.size.height * 2.0)) 
     wallRight.physicsBody?.dynamic = false 
     wallRight.physicsBody?.categoryBitMask = objectGroup 
     self.addChild(wallRight) 

     //creating the middle wall that objects pass by 
     wallMiddle.position = CGPointMake(CGRectGetMinX(self.frame), CGRectGetMinY(self.frame)) 
     wallMiddle.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.size.width, 1)) 
     wallMiddle.physicsBody?.dynamic = false 
     wallMiddle.physicsBody?.categoryBitMask = gapGroup 
     wallMiddle.physicsBody?.collisionBitMask = gapGroup 
     wallMiddle.physicsBody?.contactTestBitMask = objectGroup 
     self.addChild(wallMiddle) 

     //creating the label 
     scoreLabel.fontName = "Helvetica" 
     scoreLabel.fontSize = 60 
     scoreLabel.text = "0" 
     scoreLabel.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) + 70) 
     self.addChild(scoreLabel) 

     var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("randObject"), userInfo: nil, repeats: true) 

     var timerObjects = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("checkObjectPlace"), userInfo: nil, repeats: true) 


    } 

    func checkObjectPlace(){ 



    } 

    //function to randomly choose which object 

    func randObject(){ 
     if gameOver == 0{ 

     var rand = arc4random_uniform(6)+1 

     switch(rand){ 

     case 1: 
      leftObject() 
     case 2: 
      middleObject() 
     case 3: 
      rightObject() 
     case 4: 
      LeftAndMiddleObject() 
     case 5: 
      rightAndLeftObject() 
     case 6: 
      rightAndMiddleObject() 
     default: 
      println("error !! non a number other than 0, 1, 2 has been choosen .") 

      } 

     } 
    } 

    //function to create the left objects 

    func leftObject(){ 
     var rand = arc4random_uniform(2) + 1 
     if rand == 1 
     { 

      bigWall.position = CGPointMake(CGRectGetMinX(self.frame) + bigWall.size.width/2, CGRectGetMaxY(self.frame)) 

      var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
      var removeObjects = SKAction.removeFromParent() 
      var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 
      bigWall.runAction(moveAndRemoveObjects) 
      bigWall.physicsBody = SKPhysicsBody(rectangleOfSize: bigWall.size) 
      bigWall.physicsBody?.dynamic = false 
      bigWall.physicsBody?.categoryBitMask = objectGroup 

      movingObjects.addChild(bigWall) 

     } 
     else 
     { 

      tallWall.position = CGPointMake(CGRectGetMinX(self.frame) + tallWall.size.width/2, CGRectGetMaxY(self.frame)) 
      var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
      var removeObjects = SKAction.removeFromParent() 
      var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 
      tallWall.runAction(moveAndRemoveObjects) 
      tallWall.physicsBody = SKPhysicsBody(rectangleOfSize: tallWall.size) 
      tallWall.physicsBody?.dynamic = false 

      tallWall.physicsBody?.categoryBitMask = objectGroup 


      movingObjects.addChild(tallWall) 
     } 


    } 

    //function to create the middle objects 

    func middleObject(){ 

     var rand = arc4random_uniform(2) + 1 
     if rand == 1 
     { 
      var bigWall = SKSpriteNode(imageNamed: "shortwall") 
      bigWall.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame)) 
      var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
      var removeObjects = SKAction.removeFromParent() 
      var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 
      bigWall.runAction(moveAndRemoveObjects) 
      bigWall.physicsBody = SKPhysicsBody(rectangleOfSize: bigWall.size) 
      bigWall.physicsBody?.dynamic = false 
      bigWall.physicsBody?.categoryBitMask = objectGroup 
      movingObjects.addChild(bigWall) 
     } 
     else 
     { 
      var tallWall = SKSpriteNode(imageNamed: "tallwall") 
      tallWall.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame)) 
      var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
      var removeObjects = SKAction.removeFromParent() 
      var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 
      tallWall.runAction(moveAndRemoveObjects) 
      tallWall.physicsBody = SKPhysicsBody(rectangleOfSize: tallWall.size) 
      tallWall.physicsBody?.dynamic = false 
      tallWall.physicsBody?.categoryBitMask = objectGroup 
      movingObjects.addChild(tallWall) 
     } 

    } 

    //function to create the right objects 

    func rightObject(){ 
     var rand = arc4random_uniform(2) + 1 
     if rand == 1 
     { 
      var bigWall = SKSpriteNode(imageNamed: "shortwall") 
      bigWall.position = CGPointMake(CGRectGetMaxX(self.frame) - bigWall.size.width/2, CGRectGetMaxY(self.frame)) 
      var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
      var removeObjects = SKAction.removeFromParent() 
      var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 
      bigWall.runAction(moveAndRemoveObjects) 
      bigWall.physicsBody = SKPhysicsBody(rectangleOfSize: bigWall.size) 
      bigWall.physicsBody?.dynamic = false 
      bigWall.physicsBody?.categoryBitMask = objectGroup 
      movingObjects.addChild(bigWall) 

     } 
     else 
     { 
      var tallWall = SKSpriteNode(imageNamed: "tallwall") 
      tallWall.position = CGPointMake(CGRectGetMaxX(self.frame) - tallWall.size.width/2, CGRectGetMaxY(self.frame)) 
      var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
      var removeObjects = SKAction.removeFromParent() 
      var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 
      tallWall.runAction(moveAndRemoveObjects) 
      tallWall.physicsBody = SKPhysicsBody(rectangleOfSize: tallWall.size) 
      tallWall.physicsBody?.dynamic = false 
      tallWall.physicsBody?.categoryBitMask = objectGroup 
      movingObjects.addChild(tallWall) 

      if ball.position.x == tallWall.position.x{ 
       scoreIncrement() 
      } 
     } 


    } 

    //function to create a right and left object 

    func rightAndLeftObject(){ 

     var rand = arc4random_uniform(2) + 1 
     if rand == 1 
     { 
      var bigWall = SKSpriteNode(imageNamed: "shortwall") 
      var tallWall = SKSpriteNode(imageNamed: "tallwall") 
      tallWall.position = CGPointMake(CGRectGetMinX(self.frame) + tallWall.size.width/2, CGRectGetMaxY(self.frame)) 
      bigWall.position = CGPointMake(CGRectGetMaxX(self.frame) - bigWall.size.width/2, CGRectGetMaxY(self.frame)) 
      var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
      var removeObjects = SKAction.removeFromParent() 
      var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 
      bigWall.runAction(moveAndRemoveObjects) 
      tallWall.runAction(moveAndRemoveObjects) 
      tallWall.physicsBody = SKPhysicsBody(rectangleOfSize: tallWall.size) 
      tallWall.physicsBody?.dynamic = false 
      bigWall.physicsBody = SKPhysicsBody(rectangleOfSize: bigWall.size) 
      bigWall.physicsBody?.dynamic = false 
      bigWall.physicsBody?.categoryBitMask = objectGroup 
      tallWall.physicsBody?.categoryBitMask = objectGroup 
      movingObjects.addChild(tallWall) 
      movingObjects.addChild(bigWall) 

         bigWall.position = CGPointMake(CGRectGetMaxX(self.frame) - bigWall.size.width/2, CGRectGetMaxY(self.frame)) 
     } 
     else 
     { 
      var bigWall = SKSpriteNode(imageNamed: "shortwall") 
      var tallWall = SKSpriteNode(imageNamed: "tallwall") 
      bigWall.position = CGPointMake(CGRectGetMaxX(self.frame) - bigWall.size.width/2, CGRectGetMaxY(self.frame)) 
      tallWall.position = CGPointMake(CGRectGetMaxX(self.frame) - tallWall.size.width/2, CGRectGetMaxY(self.frame)) 
      var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
      var removeObjects = SKAction.removeFromParent() 
      var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 
      tallWall.physicsBody = SKPhysicsBody(rectangleOfSize: tallWall.size) 
      tallWall.physicsBody?.dynamic = false 
      bigWall.physicsBody = SKPhysicsBody(rectangleOfSize: bigWall.size) 
      bigWall.physicsBody?.dynamic = false 
      tallWall.runAction(moveAndRemoveObjects) 
      bigWall.runAction(moveAndRemoveObjects) 
      bigWall.physicsBody?.categoryBitMask = objectGroup 
      tallWall.physicsBody?.categoryBitMask = objectGroup 
      movingObjects.addChild(tallWall) 
      movingObjects.addChild(bigWall) 
     } 


    } 

    func rightAndMiddleObject(){ 

     var rand = arc4random_uniform(2) + 1 
     if rand == 1 
     { 
      var bigWall = SKSpriteNode(imageNamed: "shortwall") 
      var tallWall = SKSpriteNode(imageNamed: "tallwall") 
      tallWall.position = CGPointMake(CGRectGetMaxX(self.frame) - tallWall.size.width/2, CGRectGetMaxY(self.frame)) 
      bigWall.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame)) 

      var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
      var removeObjects = SKAction.removeFromParent() 
      var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 

      tallWall.runAction(moveAndRemoveObjects) 
      bigWall.runAction(moveAndRemoveObjects) 
      tallWall.physicsBody = SKPhysicsBody(rectangleOfSize: tallWall.size) 
      tallWall.physicsBody?.dynamic = false 
      bigWall.physicsBody = SKPhysicsBody(rectangleOfSize: bigWall.size) 
      bigWall.physicsBody?.dynamic = false 
      bigWall.physicsBody?.categoryBitMask = objectGroup 
      tallWall.physicsBody?.categoryBitMask = objectGroup 
      movingObjects.addChild(tallWall) 
      movingObjects.addChild(bigWall) 

     } 
     else 
     { 
      var bigWall = SKSpriteNode(imageNamed: "shortwall") 
      var tallWall = SKSpriteNode(imageNamed: "tallwall") 
      bigWall.position = CGPointMake(CGRectGetMidX(self.frame) , CGRectGetMaxY(self.frame)) 
      tallWall.position = CGPointMake(CGRectGetMaxX(self.frame) - tallWall.size.width/2, CGRectGetMaxY(self.frame)) 
      var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
      var removeObjects = SKAction.removeFromParent() 
      var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 

      tallWall.runAction(moveAndRemoveObjects) 
      bigWall.runAction(moveAndRemoveObjects) 
      tallWall.physicsBody = SKPhysicsBody(rectangleOfSize: tallWall.size) 
      tallWall.physicsBody?.dynamic = false 
      bigWall.physicsBody = SKPhysicsBody(rectangleOfSize: bigWall.size) 
      bigWall.physicsBody?.dynamic = false 
      bigWall.physicsBody?.categoryBitMask = objectGroup 
      tallWall.physicsBody?.categoryBitMask = objectGroup 
      movingObjects.addChild(tallWall) 
      movingObjects.addChild(bigWall) 
     } 


    } 

    func LeftAndMiddleObject(){ 

     var rand = arc4random_uniform(2) + 1 
     if rand == 1 
     { 
      var bigWall = SKSpriteNode(imageNamed: "shortwall") 
      var tallWall = SKSpriteNode(imageNamed: "tallwall") 
      tallWall.position = CGPointMake(CGRectGetMinX(self.frame) + tallWall.size.width/2, CGRectGetMaxY(self.frame)) 
      bigWall.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame)) 

      var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
      var removeObjects = SKAction.removeFromParent() 
      var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 

      tallWall.runAction(moveAndRemoveObjects) 
      bigWall.runAction(moveAndRemoveObjects) 
      tallWall.physicsBody = SKPhysicsBody(rectangleOfSize: tallWall.size) 
      tallWall.physicsBody?.dynamic = false 
      bigWall.physicsBody = SKPhysicsBody(rectangleOfSize: bigWall.size) 
      bigWall.physicsBody?.dynamic = false 
      bigWall.physicsBody?.categoryBitMask = objectGroup 
      tallWall.physicsBody?.categoryBitMask = objectGroup 
      movingObjects.addChild(tallWall) 
      movingObjects.addChild(bigWall) 

     } 
     else 
     { 
      var bigWall = SKSpriteNode(imageNamed: "shortwall") 
      var tallWall = SKSpriteNode(imageNamed: "tallwall") 
      bigWall.position = CGPointMake(CGRectGetMidX(self.frame) , CGRectGetMaxY(self.frame)) 
      tallWall.position = CGPointMake(CGRectGetMinX(self.frame) + tallWall.size.width/2, CGRectGetMaxY(self.frame)) 

      var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
      var removeObjects = SKAction.removeFromParent() 
      var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 

      tallWall.runAction(moveAndRemoveObjects) 
      bigWall.runAction(moveAndRemoveObjects) 
      tallWall.physicsBody = SKPhysicsBody(rectangleOfSize: tallWall.size) 
      tallWall.physicsBody?.dynamic = false 
      bigWall.physicsBody = SKPhysicsBody(rectangleOfSize: bigWall.size) 
      bigWall.physicsBody?.dynamic = false 
      bigWall.physicsBody?.categoryBitMask = objectGroup 
      tallWall.physicsBody?.categoryBitMask = objectGroup 
      movingObjects.addChild(tallWall) 
      movingObjects.addChild(bigWall) 
     } 


    } 

    func scoreIncrement(){ 

     score = score + 1 
     scoreLabel.text = "\(score)" 
    } 


    func didBeginContact(contact: SKPhysicsContact) { 

     println("contact") 

     if contact.bodyA.categoryBitMask == gapGroup || contact.bodyB.categoryBitMask == gapGroup { 

      println("gap contact") 

     } else { 

      gameOver = 1 
      movingObjects.speed = 0 

     } 
    } 

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { 
     if gameOver == 0 { 

     ball.physicsBody?.velocity = CGVectorMake(0, 0) 
     ball.physicsBody?.applyImpulse(CGVectorMake(70,0)) 

     } 

    } 

    override func update(currentTime: NSTimeInterval) { 



    } 
} 
+0

对类和方法变量使用不同的名称。 bigWall,tallWall是类变量,所以不要使用相同的变量名来初始化新的实例。 – Shoaib

错误建议你尝试将孩子添加到节点,而它已经有一个父。堆栈跟踪将您指向leftObject方法。在这里你有一个SKAction设置来移动一段时间,然后从父母中移除。

 var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height/100)) 
     var removeObjects = SKAction.removeFromParent() 
     var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects]) 
     bigWall.runAction(moveAndRemoveObjects) 

这增加了操作的节点,它运行,但你的代码路径将继续向下

movingObjects.addChild(bigWall) 

几乎瞬间。看起来像一个竞争条件,你认为代码将等待,直到动作完成后再继续。

您有一个名为bigWall的实例属性,并且在大多数方法中,您创建一个名为bigWall的本地对象并将其添加到场景中。由于每次方法调用都可以正常工作,它就是一个新对象。但是,在leftObject方法中,您没有本地对象bigWall,因此它引用了实例属性。第一次调用leftObject时,它将很好地将您的实例属性bigWall添加到场景中。第二次调用该方法时,它将尝试将bigWall实例属性添加到场景中,当它已经在场景中时,并且这将是出现错误的位置。