![](/img/trans.png)
[英]Prevent Obj-C code from passing `nil` to a Swift method with non-optional parameters
[英]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)
在實踐中,我已經使用MessageUI
的MFMailComposeViewController
API進行了此操作。 以下代碼創建了一個非可選的MFMailComposeViewController
,但是,如果用戶尚未在Mail中設置電子郵件帳戶,則以下代碼將因EXC_BAD_ACCESS
崩潰:
let mailComposeViewController = MFMailComposeViewController()
print("\(mailComposeViewController)")
調試器如下所示顯示mailComposeViewController
的值:
mailComposeViewController = (MFMailComposeViewController) 0x0000000000000000
我在這里有幾個問題:
unsafeBitCast(_:to:)
的文檔說它“破壞了Swift類型系統的保證”,但是Swift文檔中有一個地方可以解釋這些保證可以被打破,以及如何/何時? 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.