2017-09-06 4 views
0

i SKEmitterNode und SKSpriteNode einfach nur versuchen, zu verwenden, aber ich bin immer Fehler in der zweiten Zeile von meinem Codeunerwartet null gefunden, während ein optionaler Wert in GameKit Abwickeln

startfield.position = CGPoint.init(x:0,y:1200) 

und Fehler wie

"fatal error: unexpectedly found nil while unwrapping an Optional value"

2 mal und zu auch dieses

"does not have sandbox access for frZQaeyWLUvLjeuEK43hmg and IS NOT appropriately entitled"

habe ich nicht u nderstand optional Konzept so wegen, dass ich nicht in der Lage bin, es zu lösen ..

class GameScene: SKScene { 

var startfield : SKEmitterNode! 
var player : SKSpriteNode! 

    override func didMove(to view: SKView) { 
     startfield = SKEmitterNode(fileNamed: "Starfield") 
     startfield.position = CGPoint.init(x: 0, y: 1200) 
     startfield.advanceSimulationTime(10) 
     self.addChild(startfield) 
     startfield.zPosition = -1 
     //define Player 
    player = SKSpriteNode(imageNamed: "shuttle") 
    player.position = CGPoint(x: self.frame.width/2, y: player.size.height/2 + 20) 
    self.addChild(player) 
    } 

    override func update(_ currentTime: TimeInterval) { 
     // Called before each frame is rendered 
    } 
} 
+0

'SKEmitterNode (Dateiname:" Starfield ")' gibt 'nil' zurück –

+0

Typo literal' "Starfield" 'vs.' "Startfield" '? – vadian

+0

Sie haben hier auch zwei Fragen. Eines ist das 'Optional' und das andere ist der Sandbox-Zugriff. Ich würde separat nach einer Antwort auf den Sandbox-Zugangsteil suchen oder in einer anderen Frage danach fragen. – ColGraff

Antwort

1

neu deklariert Ihre starfield Variable (als startfield vertippt?), so dass es Null-Wert erlaubt:

var starfield: SKEmitterNode? 

Dies ist notwendig als SKEmitterNode(fileNamed:) ist ein optionaler Initialisierer, d. e. eine, die nil zurückgeben kann. Vor der weiteren Verwendung dieses Variablentests, falls nicht null, e. G. mit einer guard Anweisung:

guard let starfield = starfield else { return } 

Für den Rest Ihrer Funktion starfield ist nicht nil jetzt.

0

Wenn Sie eine Variable mit einem ! nach dem Typ erstellen, machen Sie es "implizit unwrapped". In der Praxis bedeutet das, dass wenn die Variable Null ist und Sie versuchen, darauf zu verweisen, Sie abstürzen.

Entfernen Sie die ! in Ihren Deklarationen.

var startfield : SKEmitterNode? 

Und dann didMove Funktion ändern, um eine Wache zu verwenden:

override func didMove(to view: SKView) { 
     startfield = SKEmitterNode(fileNamed: "Starfield") 

     guard let startfield = startfield else { 
     print("startfield is nil!") 
     return 
     } 
     startfield.position = CGPoint.init(x: 0, y: 1200) 
     startfield.advanceSimulationTime(10) 
     self.addChild(startfield) 
     startfield.zPosition = -1 
     //define Player 
    player = SKSpriteNode(imageNamed: "shuttle") 
    player.position = CGPoint(x: self.frame.width/2, y: player.size.height/2 + 20) 
    self.addChild(player) 
    } 
+0

Guter Fang. Tatsächlich können wir startField nicht ohne wesentliche Nacharbeit zu einem nicht-optionalen Objekt machen, da der Compiler Sie zwingt, allen nicht-optionalen Instanzvariablen im init einen Nicht-Null-Wert zuzuweisen. Ich habe meine Antwort bearbeitet, um sie als optional zu belassen und einen Fehler anzuzeigen, wenn der Aufruf von 'SKEmitterNode (fileNamed:)' fehlschlägt. –

+0

Zum OP: Beachten Sie, dass Ihre didMove-Funktion bei jedem Aufruf eine neue SKEmitter-Notiz erstellt. Ist es das was du willst? –

+0

Ich habe meinen ursprünglichen Kommentar bei der Bearbeitung entfernt, da dieser nicht mehr relevant war. Es liegt in der Luft, ob Sie die Eigenschaft implizit haben möchten oder nicht. Es hängt alles davon ab, wie wichtig die Immobilie für Ihr Projekt ist. Wenn es wichtig ist, dann implicitly-unwrapped ist gut - entweder scheitern würde oder mit einem Ersatz wiederherstellen, wenn nicht dann ein einfaches 'Optional' kann funktionieren. – ColGraff

1

Die Linie:

startfield = SKEmitterNode(fileNamed: "Starfield") 

Kann eine nil zurück, wenn die Datei nicht gefunden wird, aber haben Sie es in einem implizit unverpackten Optional gespeichert:

var startfield : SKEmitterNode! 

Also behandelt das System es als nicht nil, aber es ist wirklich nil. Dann, wenn Sie versuchen, eine Eigenschaft zuweisen für diese nil:

startfield.position = CGPoint.init(x: 0, y: 1200) 
// should really be: CGPoint(x: 0, y: 1200) 

Alles explodiert und Sie einen fatalen Fehler.

Stattdessen prüfen, ob die Datei korrekt geladen und dann Zuordnung zu tun:

override func didMove(to view: SKView) { 
    // Load the file into a `SKEmitterNode?` and use optional binding 
    // to attempt to unwrap into a `SKEmitterNode`. 
    guard let emitter = SKEmitterNode(fileNamed: "Starfield") else { 
    // Unwrapping failed, crash with an appropriate message. 
    fatalError("File \"Starfield\" not found.") 
    } 
    // Unwrapping succeeded, continue 
    startfield = emitter 
    // ... 
} 

Der Grund, es in ein SKEmitterNode? in erster Linie lädt ist aufgrund der Belastung in einem von SKNode geerbt failable initializer durchgeführt wird: init(fileNamed:)

convenience init?(fileNamed filename: String) 

Optional Binding ist, wenn Sie das Konstrukt if let verwenden, um eine Optional auszupacken.

Verwandte Themen