双问号,它是如何工作的?

Nic*_*tto 20 uiviewcontroller ios swift

我正在学习Swift,并且作为整个过程的一部分,试图找出这里到底发生了什么.我有一个自定义segue,我想放置我的模态视图控制器解除转换.过去在Objective-c中的内容如下:

UIViewController *sourceViewController = self.sourceViewController;
[sourceViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];
Run Code Online (Sandbox Code Playgroud)

self是一个实例UIStoryboardSegue.我在Swift中将此片段翻译为:

self.sourceViewController.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

从编译器获取此错误:

"的UIViewController?没有名为'dismissViewControllerAnimated'的成员

现在,通过文档,该presentingViewController方法如下所示:

var presentingViewController: UIViewController? { get }
Run Code Online (Sandbox Code Playgroud)

根据我对Swift语言文档的理解,?应该解包该值,如果有的话.在这种情况下,视图控制器.无法解释的事实是:如果我提出一个双重问号,它会编译并且有效:

self.sourceViewController.presentingViewController??.dismissViewControllerAnimated(true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

有人能告诉我我错过了什么吗?该怎么办?

Gab*_*lla 20

额外的?要求是sourceViewController返回AnyObject而不是a UIViewController.这是来自Objective-C的API转换中的一个缺陷(其中这样的属性返回相当无意义id).它仍然是一个从iOS 8 beta 5开始的持续过程,显然这些API尚未修复.

如果您提供适当的演员表,它将按预期工作

(self.sourceViewController as UIViewController).presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

现在,为什么我们?在处理时需要额外的AnyObject

AnyObject可以代表任何对象类型,就像idObjective-C.因此,在编译时,您可以调用其上的任何现有方法sourceViewController.

当你这样做时,它触发从隐含低垂AnyObjectUIViewController并根据官方指导价:

与Swift中的所有向下转换一样,转换AnyObject为更具体的对象类型并不能保证成功,因此返回一个可选值

所以,当你这样做

self.sourceViewController.presentingViewController??
Run Code Online (Sandbox Code Playgroud)

它含蓄地转化为类似的东西

 let source: UIViewController? = self.sourceViewController as? UIViewController
 let presenting: UIViewController? = source?.presentingViewController
Run Code Online (Sandbox Code Playgroud)

这就是为什么你需要两个?:一个用于解决向下转换,另一个用于解决presentingViewController.

最后,始终根据文档:

当然,如果您确定对象的类型(并且知道它不是nil),则可以使用as运算符强制调用.

这正是我上面提出的解决方案.

  • @GeorgeTaskos是的,这可以做到,即使该片段只作为解释,所以我更喜欢尽可能明确. (2认同)