繁体   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