簡體   English   中英

在Swift中檢查非可選值是否為nil的最佳方法

[英]Best way to check non-optional values for nil in Swift

在Swift中,這種情況很少見,但最終可能會得到一個非零類型的值,該值具有nil值。 如對這個問題的回答所述 ,這可能是由橋接到Swift的不良Objective-C代碼引起的:

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

或通過錯誤的Swift代碼:

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

在實踐中,我已經使用MessageUIMFMailComposeViewController API進行了此操作。 以下代碼創建了一個非可選的MFMailComposeViewController ,但是,如果用戶尚未在Mail中設置電子郵件帳戶,則以下代碼將因EXC_BAD_ACCESS崩潰:

let mailComposeViewController = MFMailComposeViewController()
print("\(mailComposeViewController)")

調試器如下所示顯示mailComposeViewController的值:

mailComposeViewController = (MFMailComposeViewController) 0x0000000000000000

我在這里有幾個問題:

  1. 我注意到unsafeBitCast(_:to:)文檔說它“破壞了Swift類型系統的保證”,但是Swift文檔中有一個地方可以解釋這些保證可以被打破,以及如何/何時?
  2. 檢查這種情況的最好,最慣用的方法是什么? 編譯器不會讓我檢查mailComposeViewController == nil因為它不是可選的。

甚至Apple的API有時也會針對API中未標記為Optional的類型返回nil 解決方案是將其分配給Optional。

例如,有一段時間traitCollectionDidChange返回了一個UITraitCollection,即使它實際上可能是nil 您無法將其檢查為nil因為Swift不會讓您檢查nil的non-Optional。

解決方法是立即將返回值分配給UITraitCollection? 檢查nil 無論您的用例是什么,這種事情都應該起作用(盡管您的郵件示例不是用例,因為您一開始就做錯了)。

我有同樣的問題,但我使用了蘋果文檔中的建議。

從文檔中:

在呈現郵件撰寫視圖控制器之前,請始終調用canSendMail()方法以查看當前設備是否配置為發送電子郵件。 如果未將用戶的設備設置為可以發送電子郵件,則可以通知用戶或僅在應用程序中禁用電子郵件發送功能。 如果canSendMail()方法返回false,則不應嘗試使用此接口。

if !MFMailComposeViewController.canSendMail() {
    print("Mail services are not available")
    return
}

考慮使用unsafeBitCast(_:to:)

主要問題在於,在此方法中,如果該指針可以符合我們期望的類型,則無需任何驗證就可以將指針從Swift轉換為值,從我的角度來看,這很危險,因為它會導致崩潰。

使用實際的Swift指針類型可能有更好的方法,但是一種選擇可能是僅查看地址:

func isNull(_ obj: AnyObject) -> Bool {
    let address = unsafeBitCast(obj, to: Int.self)
    return address == 0x0
}

Int被記錄為機器字大小。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM