2016-05-24 9 views
0

Ich habe den Code unten und es funktioniert gut, aber ich hatte erwartet, die Linie print(john.residence!.numberOfRooms) zum Absturz zu bringen, wie mein numberOfRooms Variable nil Wert hat, und ich bin nicht gezwungen, unter Verwendung von Umbruch, wenn der Wert als Argument an print() übergeben wird. Kann mir bitte jemand erklären, warum dies keinen Laufzeitfehler auslöst und stattdessen nil sicher druckt?Drucke ohne Kraft-auspackt Eigenschaft lösen keine Laufzeitfehler in Swift

class Person { 
    var residence: Residence? 
} 

class Residence { 
    var numberOfRooms: Int? 
} 

let john = Person() 

john.residence = Residence() 

print(john.residence!.numberOfRooms) 
+0

max. Nur um Dinge zu klären, werden Sie nicht gezwungen, einen Nullwert auszupacken. Sie sind Kraft auf John.Residence auspacken und es hat einen Wert. – BangOperator

Antwort

2

Was machst du Optional Chaining genannt wird. Sowohl Optional Chaining und Zwangs Auswickeln das gleiche tun, aber:

The main difference is that optional chaining fails gracefully when the optional is nil, whereas forced unwrapping triggers a runtime error when the optional is nil.

“The Swift Programming Language (Swift 2.2).” iBooks. https://itun.es/br/jEUH0.l

Sie sind Kraft, um die .residence Eigenschaft auspackt, die nicht nil ist: Es enthält eine Residence Instanz, die ihre .numberOfRooms Eigenschaft als nil gesetzt hat, weil es wurde nicht initialisiert. Da Sie es nicht zwangsweise auspacken müssen, werden aufgrund der optionalen Verkettung keine Fehler angezeigt. Versuchen Kraft Abwickeln die .numberOfRooms Eigenschaft stattdessen einen Fehler zu erhalten:

print(john.residence!.numberOfRooms!) 

Oder Sie die folgende Zeile .residence als nil einzustellen entfernen:

john.residence = Residence() 

Auf diese Weise john keine .residence hat, so versucht, force unwrap bewirkt, dass der Swift-Compiler einen Laufzeitfehler auslöst.

+0

Ok macht Sinn, aber noch eine Frage, warum sollte ich John.residence !.Anzahl der Räume! wenn ich john.residence! .numberOfRooms verwenden kann, um meinen Wert zu erhalten. – Max

+0

Wenn Sie '.numberOfRooms!' Verwenden, geben Sie an, dass Sie absolut sicher sind, dass diese Eigenschaft nicht 'nil' zurückgibt. Dies ist für Debugging-Zwecke nützlich, denn wenn Sie erwarten, dass ein Wert nicht "nil" ist und "nil" zurückgibt, wird Ihr Programm die Ausführung schnell stoppen. Dadurch werden indirekte Fehler vermieden, die dadurch verursacht werden, dass Werte "null" sind, wo sie nicht sollten. –

+0

@Max siehe meine aktualisierte Antwort für weitere Erklärungen über die optionale Verkettung. –

0

Ihre App stürzt nicht ab, weil Sie Eigenschaft definieren numberOfRooms mit ?. Es bedeutet, dass es auch Nullwert erlaubt.

Verwenden Sie ! anstelle von ?. Es wird definitiv auf diese Aussage stürzen.

print(john.residence!.numberOfRooms) 

Besuchen Sie diesen Link, um es Ihnen, den Unterschied zwischen verstehen helfen? und !.
Difference Between ? and ! in Swift Language?

+0

Was Sie beschreiben, ist ein _implicitly unwrapped option_, und das OP-Problem bezieht sich darauf, warum sein Code, der eine _optional Kette_ enthält, keinen Laufzeitfehler zurückgibt. –

+0

@Bhumilka john.residence! .numberOfRooms wird nicht abstürzen, bitte überprüfen. es würde einen Nullwert drucken – Max

+0

@Max er sagt, dass, wenn Sie die 'Residence'-Initialisierung als' var numberOfRooms: Int! '(Ersetzen von **? ** durch **! ** hier) die' print'-Funktion verursachen Versagen. Verwenden Sie dies jedoch nicht. Mehr zu Implically Unwrapped Optionals hier: http://stackoverflow.com/questions/24006975/why-create-implicitly-unwrapped-optional –

-1

I was expecting this line (print(john.residence!.numberOfRooms)) to crash as my numberOfRooms variable has nil value

print() druckt die Werte innerhalb des optionalen oder "Null" ohne Notwendigkeit unwrap zu erzwingen. Wir müssen keine unverpackten Typen für print() bereitstellen. Selbst wenn wir dies tun, müssen wir sicherstellen, dass es einen Wert innerhalb der Option gibt.

UPDATE:

Max. Nur um die Dinge zu klären, sind Sie nicht zwingen, auf einem Nullwert auszupacken. Sie sind gezwungen, john.residence auszupacken und es hat einen Wert. Sie drucken gerade ein optionales. Das würde den 'optionalen Wert' oder 'Null' ausgeben. Und wenn Sie sich wundern, warum Optionals während des Druckens keinen Fehler geben, ist es, weil print() entweder den optionalen Wert oder Nil druckt. Es stürzt nicht auf Nullwerte ab.

+0

Falsch. 'print (john.residence! .numberOfRooms!)' löst einen Laufzeitfehler aus. Der Fehler wird nicht in seinem Code ausgelöst, da _optional chaining_ im Hintergrund fehlschlägt, nicht aufgrund der Art, wie 'print()' funktioniert. –

+0

@TiagoMarinho Vielleicht habe ich die Frage falsch beantwortet. Er fragte, warum 'numberOfRooms' mit null Wert nicht abstürzt. Selbst ich hatte diesen Gedanken früher, dass der Zugriff auf optional mit Nullwert einen Fehler ergibt. Und drucken Sie Zugriff auf das optionale ohne Fehler zu geben. Der Grund ist, dass der Druck beide Fälle sehr gut behandelt. Und ich hatte diese Frage beantwortet, "Warum gibt Drucken keinen Fehler während des Druckens nicht optional?". In diesem Zusammenhang ist keine meiner Aussagen falsch. – BangOperator

+0

Und das ist der Grund, warum ich nicht hinzugefügt hatte "und ich verwende erzwungene Auspacken von Ausrufezeichen" in dem Zitat als Es war sinnlos in dem Kontext ich verstand die Frage. – BangOperator