我对此感到困惑。例如,如果我们在cellForRowAtIndexPath:
中采用方法UITableView
,则其方法签名为:
func cellForRowAtIndexPath(_ indexPath: NSIndexPath!) -> UITableViewCell!
它的返回值是:
表示表格单元格的对象,如果单元格不可见或indexPath超出范围,则为nil。
这听起来像是使用标准选配件的完美理由。事实上,由于Objective-C中所有基于指针的类型都可以为nil ......似乎所有Objective-C指针类型都应该作为标准选项导入。
我从WWDC的演讲中得知,他们说这是隐含的未解决的选项:
来自Apple的Using Swift with Cocoa and Objective-C:
当您访问此类可选类型的值而不首先安全地展开它时,隐式解包的可选项会检查该值是否缺失。如果缺少该值,则会发生运行时错误。
因此,他们不是将可能的nil值导入Swift作为可选项,而是决定将其导入为声明永远不会为零的东西......但可能是?听起来他们通过这样做完全否定了Swift for Objective-C API中可选类型的安全性。我似乎缺少什么?
他们没有给出编译时错误或警告,而是认为运行时错误更好?这非常令人困惑。
考虑到似乎没有什么能回答我所看到的这个问题...我认为对于其他所有人来说,我只是没有看到,但是......为什么会这样?
当他们在Swift中使用Objective-C API时,是否真的只是为了避免使用if let
或可选链接?或者更多?
答案 0 :(得分:5)
当你在Swift中创建一个隐式解包的可选项时,并不意味着它总是非零:所有这意味着你告诉编译器当你访问它们的属性时,你希望对象是非 - nil
。您可以显式检查您引用的对象nil
;将其设置为nil
也不会导致异常,除非您在此之后尝试访问其任何属性。
当Apple对
的参数使用隐式解包的选项时func tableView(_ tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
功能,它们可以节省一些额外的if
- let
。在这种情况下,他们知道他们从来没有通过你nil
;在其他情况下,他们不知道,他们希望你nil
- 检查对象。
他们也允许您返回nil
。他们应该检查nil
的结果,当然,除非您决定自己调用该功能。虽然我无法想出从您自己的代码中拨打cellForRowAtIndexPath
的正当理由,但如果您拨打电话,则有责任检查nil
的返回值。
如果您考虑替代制作参数UITableView?
和NSIndexPath?
,则所有实现都必须在tableView
和indexPath
之后使用感叹号,或者使用if
- let
成语。{{1}} - {{1}}成语。与此选择相比,隐式展开的类型看起来是更好的选择。
答案 1 :(得分:3)
以下是Greg Parker's answer中swift-users的lists.swift.org:
导入为隐式解包的可选项是一种可用性 的折衷即可。大多数Objective-C指针实际上都不是零。如果指针为nil,并且作者没有检查,那么该过程 故意停止。这并不比你得到的行为更糟糕 编写Objective-C代码。 IUO导入旨在成为权宜之计。我 n长期来说,每个Objective-C接口都应该明确注释,以便Swift 可以更精确地导入它们。在您自己的代码中,您可以使用 头文件中的NS_ASSUME_NONNULL_BEGIN / END。每个未注释的 这些标记内的对象指针是非空的。