为什么Objective-C API返回隐含的解包选项?

我对此感到困惑。 如果我们以UITableView的方法cellForRowAtIndexPath:为例,它的方法签名是:

 func cellForRowAtIndexPath(_ indexPath: NSIndexPath!) -> UITableViewCell! 

其回报值是:

表示单元格的对象,或者如果单元格不可见或indexPath超出范围,则为nil。

这听起来像是使用标准可选的完美理由。 实际上,由于Objective-C中所有基于指针的types都可以是零,所以所有的Objective-C指针types都应该作为标准选项来导入。

我从WWDC的谈话中知道,他们认为,对于隐含的解包选项:

  • 可以明确地testing为零
  • 可以直接访问底层值的属性/方法
  • 可以隐式转换为其基础值

从Apple的Cocoa和Objective-C中使用Swift,

当您访问这种types的可选types的值时,如果不安全地解包它,隐式解包的可选操作将检查值是否丢失。 如果缺less该值,则会发生运行时错误。

所以,他们决定把它作为一个声明,说它永远不应该是零,但可能是一个可选项,而不是将一个可能的零值导入到Swift中。 这听起来像是他们完全否定了Swift中Objective-C API的可选types的安全性。 我似乎错过了什么?

他们没有给出编译时间错误或警告,而是认为运行时错误更好? 这很混乱。

考虑到似乎没有任何东西可以回答我所看到的这个问题……我认为这是其他人显而易见的,我只是没有看到,而是……为什么这样呢?

是否真的只是为了避免人们在Swift中使用Objective-C API时使用或不使用链接,或者更多?

当你在Swift中隐式地展开可选项时,并不意味着它总是非零:所有这一切意味着你告诉编译器,当你访问它们的属性时,你期望对象是非零。 您引用的对象可以显式检查nil ; 将其设置为nil也不会导致exception,除非您在此之后尝试访问其任何属性。

当苹果公司使用隐含的unwrapped选项的参数

 func tableView(_ tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! 

function,他们让你节省一些额外的, iflet 。 在这种情况下,他们知道他们永远不会通过你; 在其他情况下,他们不知道,他们希望你nil检查对象。

他们也允许你返回nil 。 除非你决定自己调用这个函数,否则由他们来检查结果nil 。 虽然我想不出从你自己的代码中调用cellForRowAtIndexPath的有效理由,但是如果你确实打了一个电话,那么检查返回值为nil是你的责任。

如果你考虑使参数UITableView?的替代schemeUITableView?NSIndexPath? 相反,所有的实现都必须在tableViewindexPath之后使用感叹号,或者使用iflet成语。 与此select相比,隐式解包types看起来更好。

 The following was Greg Parker's answer which made some sense the reasons, referred by swift-users@swift.org: 

导入为隐式解包可选是一个可用性的妥协 。 大多数Objective-C指针从来都不是零。 如果一个指针是零,并且作者没有检查,那么该过程故意停止。 这并不比编写Objective-C代码时的行为更糟​​糕。 IUOimport意在成为权宜之计。 从长远来看,每个Objective-C接口都应该被明确的注释,以便Swift可以更精确地导入它们。 在你自己的代码中,你可以在头文件中使用NS_ASSUME_NONNULL_BEGIN / END。 这些标记内的每个未注释的对象指针都是非空的。