2015-12-27 83 views
1

我試圖從一個場景轉換到另一個場景,但是當我撥打presentScene時發生崩潰! 場景未存儲在課程中或被引用,它們直接加載到presentScene調用中。在XcodeSceneKit presentScene(_withTransition:incomingPointOfView completionHandler)crash with dynamic loaded SCNScene

截圖崩潰: crash screencap

我簡單最少的項目是在這裏:https://dl.dropboxusercontent.com/u/6979623/SceneKitTransitionTest.zip

MKScene只是一個SCNScene子類,因爲我想知道,當一個場景deinited以確保這就對了。

self.gameView!.scene = MKScene(named:"art.scnassets/scene1.scn") 

再後來我打電話

let scnView:SCNView = self.gameView! as SCNView 
let skTransition:SKTransition = SKTransition.crossFadeWithDuration(1.0) 
skTransition.pausesIncomingScene = false 
skTransition.pausesOutgoingScene = false 
self.sceneToggler = !self.sceneToggler 
// transition 
scnView.presentScene((self.sceneToggler ? MKScene(named:"art.scnassets/scene1.scn")! : MKScene(named:"art.scnassets/scene2.scn")!), withTransition:skTransition, incomingPointOfView:nil, completionHandler:nil) 

如果我繼續在我的課,然後它工作現場的參考 - 但是這不是我想要的。我只想轉換到不同的場景,並將當前場景留在後面。

爲什麼會崩潰? 這似乎是一個簡單的任務...

回答

3

這是一個在SceneKit中的錯誤。解決方法:在調用「presentScene」之前保留對傳出場景的引用,並在該調用之後將其釋放。

+1

在SceneKit中有很多bug需要解決方法 - 希望你們解決它們並讓你的質量提高! – StackUnderflow

2

我能夠通過一個更簡單的項目來重現您的崩潰。它不使用MKScene,也不使用通知來觸發轉換。它在第二次加載時崩潰。

我已經在https://bugreport.apple.com上提交過rdar:// 24012973,這是我想要的,以及您的較長項目。

這是我簡化的ViewController.swift。在SCNScene屬性(第25/29行)或即時載入(第24/28行)之間切換會在正確和崩潰行爲之間切換。也就是說,

 nextScene = SCNScene(named:"art.scnassets/scene2.scn")! 

失敗,

 nextScene = scene2! 

作品。

// ViewController.swift 
import Cocoa 
import SceneKit 
import SpriteKit 

class ViewController: NSViewController { 

@IBOutlet weak var sceneView: SCNView! 
private var sceneToggler:Bool = false 
private var scene1: SCNScene? = SCNScene(named:"art.scnassets/scene1.scn") 
private var scene2: SCNScene? = SCNScene(named:"art.scnassets/scene2.scn") 

private func nextSceneToLoad() -> SCNScene { 
    let nextScene: SCNScene 

    if (sceneToggler) { 
     //nextScene = SCNScene(named:"art.scnassets/scene1.scn")! 
     nextScene = scene1! 
     print ("scene1") 
    } 
    else { 
     nextScene = SCNScene(named:"art.scnassets/scene2.scn")! 
     //nextScene = scene2! 
     print ("scene2") 
    } 
    print (nextScene) 
    sceneToggler = !sceneToggler 
    return nextScene 
} 

override func mouseUp(theEvent: NSEvent) { 

    let skTransition:SKTransition = SKTransition.fadeWithDuration(5.0) 
    skTransition.pausesIncomingScene = false 
    skTransition.pausesOutgoingScene = false 
    sceneView.presentScene(nextSceneToLoad(), 
     withTransition:skTransition, 
     incomingPointOfView:nil, completionHandler:nil) 


    super.mouseUp(theEvent) 
} 
} 
+0

是的,它的工作原理。但它保持對兩個場景的引用=內存浪費。 – StackUnderflow

+2

根據@ toyos的說明,這就是你堅持的,拿走或離開它的。根據您使用兩個真實場景文件進行的儀器測量,內存使用真的是一個問題嗎?重複我發佈的雷達號,以獲得更好的注意力。如果它是一個真正的問題,你可以在完成處理程序中釋放對傳出場景的引用。但是這聽起來像是一種過早的優化。 –

+0

這是我所做的工作。 'private var mTempSceneReference:AnyObject?''和'self.mTempSceneReference = self.gameView!.scene //捕獲當前場景以便我們不會崩潰,然後在完成處理程序中self.mTempSceneReference = nil //釋放當前場景scene' – StackUnderflow