为什么Objective-C API会隐式返回未包装的选项? [英] Why do Objective-C APIs return implicitly unwrapped optionals?

查看:82
本文介绍了为什么Objective-C API会隐式返回未包装的选项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对此感到困惑。如果我们在 UITableView 中采用方法 cellForRowAtIndexPath:,它的方法签名是:

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

其返回值为:


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


这听起来像是使用标准可选项的完美理由。事实上,由于Objective-C中所有基于指针的类型都可以为nil ......似乎有意义的是所有Objective-C指针类型都应该作为标准选项导入。



<我从WWDC的谈话中得知,他们说这是隐式解包的选项:




  • 可以明确测试nil

  • 可以直接访问基础值的属性/方法

  • 可以隐式转换为其基础值



来自Apple的将Swift与Cocoa和Objective-C一起使用


当您访问这种可选类型的值在没有安全地首先展开的情况下,隐式展开的可选项检查值是否缺失。如果缺少该值,则会发生运行时错误。


因此,不是将可能的nil值作为可选项导入Swift,而是决定把它作为一种东西来说明,这应该永远不会是......但可能是?听起来他们通过这样做完全否定了Swift for Objective-C API中可选类型的安全性。我似乎缺少什么?



他们认为运行时错误更好,而不是给出编译时错误或警告?这是非常令人困惑的。



考虑到我似乎没有回答这个问题......我认为这对其他人来说是显而易见的我不是看到但是......为什么会这样?



如果让让人们免于使用或者在Swift中使用Objective-C API时的可选链接,还是更多?

解决方案

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



当Apple使用隐式解包的选项为参数

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

功能,如果 $ c> - 。在这种情况下,他们知道他们从未通过你 nil ;在其他情况下,他们不知道,他们希望你 nil - 检查对象。



他们允许你返回 nil 。他们应该检查 nil 的结果,当然,除非您决定自己调用该函数。虽然我想不出从你自己的代码调用 cellForRowAtIndexPath 的正当理由,如果你打电话,你有责任检查<$ c的返回值$ c> nil



如果你考虑制作参数的替代方法 UITableView? NSIndexPath?相反,所有实现都必须在 tableView indexPath ,或使用 if - let idiom。与此选择相比,隐式展开类型看起来是更好的选择。


I am rather perplexed by this. If we take the method cellForRowAtIndexPath: in UITableView for example, it's method signature is:

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

And its return value is:

An object representing a cell of the table or nil if the cell is not visible or indexPath is out of range.

That sounds like the perfect reason to use a standard optional. In fact, since all pointer based types in Objective-C can be nil... it seems to make sense that all Objective-C pointer types should be imported as standard optionals.

I know from the WWDC talk that they say that for implicitly unwrapped optionals:

  • Can be tested explicitly for nil
  • Can directly access properties/methods of the underlying value
  • Can be implicitly converted to its underlying value

And from Apple's Using Swift with Cocoa and Objective-C:

When you access the value in this kind of optional type without safely unwrapping it first, the implicitly unwrapped optional checks whether the value is missing. If the value is missing, a runtime error occurs.

So, instead of importing a possibly nil value into Swift as an optional, they decided to import it as something that states that this should never be nil... but could be? It sounds like they completely negated the safety of the optional type in Swift for Objective-C APIs by doing this. What do I seem to be missing?

Instead of giving a compile time error or warning, they decided a runtime error was better? This is very confusing.

Considering that nothing seems to answer this question that I have seen... I am thinking it is something obvious to everybody else that I am just not seeing but... Why is it like this?

Is it really just to save people from using if let or optional chaining when they use Objective-C APIs in Swift, or something more?

解决方案

When you make an implicitly unwrapped optional in Swift, it does not mean that it is always going to be non-nil: all it means is that you tell the compiler that when you access their properties, you expect the object to be non-nil. The object that you reference can be explicitly checked for nil; setting it to nil will not cause an exception either, unless you try to access any of its properties after that.

When Apple used implicitly unwrapped optionals for the parameters of

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

function, they let you save on a few extra if - let. In this case, they know that they never pass you a nil; in other cases, they do not know it, and they expect you to nil-check the object.

They allow you to return nil, too. It is up to them to check the results for nil, unless, of course, you decide to call that function yourself. Although I cannot think of a valid reason to call cellForRowAtIndexPath from your own code, if you do make a call, it would be your responsibility to check the return value for nil.

If you consider an alternative of making the parameters UITableView? and NSIndexPath? instead, all implementations would have to either use an exclamation point after tableView and indexPath, or use the if - let idiom. Compared to this choice, implicitly unwrapped types look like a better choice.

这篇关于为什么Objective-C API会隐式返回未包装的选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆