2017-07-21 14 views
14

Apple documentation TN2151 mówi to za możliwą przyczynę EXC_BREAKPOINT/SIGTRAP:W jaki sposób wartość nieopcjonalna otrzymuje wartość zerową?

a non-optional type with a nil value

But kodu takiego jak ten nie zostanie skompilowany:

var x = "hello" 
x = nil 

Więc jakich sytuacjach może non-opcja uzyskania wartość nil?

+1

Przeczytaj to https://stackoverflow.com/questions/34644128/why-non-optional-any-can-hold-nil/34644243. Daje to miłe wyjaśnienie. –

Odpowiedz

20

rozważyć coś takiego w Objective-C mostem SWIFT:

- (NSObject * _Nonnull)someObject { 
    return nil; 
} 

funkcja jest adnotacją _Nonnull, ale zwróci nil. Zostało to połączone jako obiekt nie-opcjonalny do Swift i ulegnie awarii.

+4

To jest najczęstsza przyczyna. Było kilka interfejsów API iOS (i macOS) niepoprawnie oznaczonych jako "_Nonnull". –

+0

Zobacz na przykład sekcję zatytułowaną "Nullability" w [AppKit Release Notes for macOS 10.13] (https://developer.apple.com/library/content/releasenotes/AppKit/RN-AppKit/index.html): "Naprawiliśmy liczba miejsc, w których argumenty i wartości zwracane miały nieprawidłowy odczyt wartości null. " –

-2

Nie wiem na pewno, ale może to się dzieje, jeśli wymusić rozpakować opcjonalnego do zmiennej dla Opcjonalne tak (!):

let a : String? = nil 
var x = "hello" 
x = a! 

Ale to tylko przypuszczenie ...

+0

To nadal wykorzystuje opcje. OP pyta o awarię z nie-opcjonalnym typem. – JAL

+0

mhm ok, chyba masz rację –

+0

W rzeczywistości twój program zawiesi się z 'fatalnym błędem: nieoczekiwanie znalazł zero podczas rozpakowywania wartości opcjonalnej." –

1

Zaczyna się podczas współpracy z Objective C. Metoda objc może być opisana jako nonnull, ale nic nie przeszkadza jej w powrocie do powrotu nil. Kompilator łapie tylko najbardziej oczywiste przypadki, a nawet wtedy produkuje tylko ostrzeżenia (np kiedy blatently return nil; w sposób, który jest określony jako nie wraca nil).

7

wymyślony, ale możliwe:

class C {} 

let x: C? = nil 
let y: C = unsafeBitCast(x, to: C.self) 

print(y) // boom 
+2

Lub po prostu' unsafeBitCast (0, to: C.self) ' – Hamish

+2

Spada z powrotem na [Obiektywne] C rzuca, aby strzelić sobie w stopę, zawsze elegancko :) – JAL

+3

Tylko uwaga: unsafeBitCast się powiedzie, ponieważ dla typu odniesienia instancje 'C' i' C? 'Są wskaźnikami, a więc tego samego rozmiaru. Z 'struct C {}' unsafeBitCast już się zawiesił (nie może być niebezpiecznyBitCast pomiędzy typami różnych rozmiarów). –

Powiązane problemy