Ответ 1
Дополнительный ?
требуется sourceViewController
вернуть AnyObject
вместо UIViewController
. Это недостаток в преобразовании API из Objective-C (в котором такое свойство возвращает довольно бессмысленный id
). Это все еще продолжающийся процесс, который начался с iOS 8 beta 5, и, по-видимому, эти API еще не исправлены.
Если вы предоставите соответствующий бросок, он будет работать как ожидалось
(self.sourceViewController as UIViewController).presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
Теперь, зачем нам понадобиться дополнительный ?
при работе с AnyObject
?
AnyObject
может представлять любой тип объекта, в основном, как id
в Objective-C
. Поэтому во время компиляции вы можете вызывать на нем любой существующий метод, например sourceViewController
.
Когда вы это сделаете, он вызывает неявное понижение от AnyObject
до UIViewController
и в соответствии с официальным руководством :
Как и во всех downcasts в Swift, отбрасывание из
AnyObject
в более конкретный тип объекта не гарантируется и, следовательно, возвращает необязательное значение
Итак, когда вы делаете
self.sourceViewController.presentingViewController??
он неявно переводит на что-то вроде
let source: UIViewController? = self.sourceViewController as? UIViewController
let presenting: UIViewController? = source?.presentingViewController
и что вам нужно два ?
: один для разрешения downcast и один для presentingViewController
.
Наконец, всегда в соответствии с документацией:
Конечно, если вы уверены в типе объекта (и знаете, что это не ноль), вы можете принудительно вызвать вызов с помощью оператора as.
который является именно моим предложенным решением выше.