2017-07-21 19 views
14

Các Apple documentation TN2151 nói điều này cho một nguyên nhân có thể của một EXC_BREAKPOINT/SIGTRAP:Giá trị không tùy chọn có được giá trị nil như thế nào?

a non-optional type with a nil value

Tuy nhiên, mã như thế này sẽ không biên dịch:

var x = "hello" 
x = nil 

Vì vậy, trong hoàn cảnh nào một tổ chức phi tùy chọn có thể có được Giá trị nil?

+1

đọc này https://stackoverflow.com/questions/34644128/why-non-optional-any-can-hold-nil/34644243. Nó đưa ra một lời giải thích tốt đẹp. –

Trả lời

20

Hãy xem xét một cái gì đó như thế này trong Objective-C bắc cầu để Swift:

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

chức năng được chú thích như _Nonnull, nhưng sẽ trở lại con số không. Điều này được bắc cầu như một đối tượng không bắt buộc đối với Swift và sẽ sụp đổ.

+4

Đây là nguyên nhân phổ biến nhất. Đã có một loạt các API iOS (và macOS) không được gắn nhãn '_Nonnull'. –

+0

Xem ví dụ phần có tiêu đề “Nullability” trong [Ghi chú phát hành AppKit cho macOS 10.13] (https://developer.apple.com/library/content/releasenotes/AppKit/RN-AppKit/index.html): “Chúng tôi đã khắc phục một số nơi mà đối số và giá trị trả lại có giá trị không chính xác. ” –

-2

I Do not biết chắc chắn, nhưng có lẽ điều này xảy ra nếu bạn ép Unwrap một tùy chọn vào biến không bắt buộc như thế này (!):

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

Nhưng nó chỉ là một phỏng đoán ...

+0

Điều này vẫn sử dụng các tùy chọn. OP hỏi về sự cố với loại không bắt buộc. – JAL

+0

mhm ok, tôi đoán bạn đúng –

+0

Thực tế, chương trình của bạn sẽ bị lỗi với "lỗi nghiêm trọng: bất ngờ tìm thấy nil trong khi mở một giá trị tùy chọn.' –

1

Xảy ra khi tương tác với mục tiêu C. Phương pháp objc có thể được chú thích là nonnull, nhưng không có cách nào ngăn không cho trả lại nil anyways. Trình biên dịch bắt chỉ các trường hợp rõ ràng nhất và thậm chí sau đó nó chỉ tạo ra cảnh báo (ví dụ như khi bạn blatently return nil; trong một phương pháp được quy định như không trở về con số không.)

7

giả tạo, nhưng có thể:

class C {} 

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

print(y) // boom 
+2

Hoặc chỉ' unsafeBitCast (0, đến: C.self) ' – Hamish

+2

Rơi vào [Objective-] C phôi để tự bắn mình vào chân, luôn thanh lịch :) – JAL

+3

Chỉ cần một chú thích: unsafeBitCast thành công vì một kiểu tham chiếu, các cá thể của 'C' và' C? 'Là các con trỏ và do đó có cùng kích thước. Với 'struct C {}' unsafeBitCast sẽ bị lỗi (không thể unsafeBitCast giữa các loại kích thước khác nhau). –

Các vấn đề liên quan