Свойство window
из UIApplicationDelegate
протокола объявляется следующим образом:
optional var window: UIWindow? { get set }
Это означает, что это необязательное свойство (в том смысле, что «класс, реализующий UIApplicationDelegate
протокол не предлагается реализовать/иметь это свойство ", как если у вас есть @optional
в Objective-C), и это свойство имеет дополнительный типOptional<UIWindow>
(или UIWindow?
).
Именно поэтому у вас есть двойной необязательный тип, в конце концов, потому что window
свойство может или не может быть реализован в realDelegate, и если да, то это будет сам тип Optional<UIWindow>
/UIWindow?
.
Поэтому в основном то, что вы хотите, чтобы вернуть window
свойство вашего realAppDelegate
... только если realAppDelegate
решил объявить, что собственность сама (что она не требует, чтобы сделать, так как это optional var
).
- Если
realAppDelegate
не реализовывали window
себя, вы, вероятно, намерены вернуть nil
UIWindow?
в результате.
- Если ваш
realAppDelegate
действительно реализовал свойство window
, тогда вам необходимо вернуть его как есть (пусть эта реализация возвращает фактический UIWindow
или nil
).
Самый простой способ сделать это - использовать оператор ниль-коалесценции ??
в Swift. a ?? b
означает, что «если a не является ником, то возвращает a, но если a равно nil, верните b» (где, если a
имеет тип T?
, тогда ожидается, что все выражение вернет объект типа T
, где в вашем случай T
- это тип UIWindow?
).
var window: UIWindow? {
get {
// If realAppDelegate.window (of type UIWindow??) is not implemented
// then return nil. Otherwise, return its value (of type UIWindow?)
return realAppDelegate.window ?? nil
// That code is equivalent (but more concise) to this kind of code:
// if let w = realAppDelegate.window { return w } else return nil
}
...
}
Для реализации сеттер, это еще одна проблема. Согласно this SO answer, прямой доступ к установщику необязательного свойства протокола не представляется возможным. Но вы можете себе представить, хак, чтобы обойти это, объявив другой протокол, который делает это требование window
свойства является обязательным, а затем попытаться бросить ему в инкубаторе:
@objc protocol UIApplicationDelegateWithWindow : UIApplicationDelegate {
var window: UIWindow? { get set }
}
class AppDelegateWrapper : UIApplicationDelegate {
...
var window: UIWindow? {
get {
return realAppDelegate.window ?? nil
}
set {
if let realAppDelWithWindow = realAppDelegate as? UIApplicationDelegateWithWindow
{
// Cast succeeded, so the 'window' property exists and is now accessible
realAppDelWithWindow.window = newValue
}
}
}
...
}
Некоторые больше информации о вложенных дополнительных опциях: [Swift в блоге] (https://developer.apple.com/swift/blog/?id=12) и [связанный вопрос] (http://stackoverflow.com/questions/27225232/two-or-more-optionals-in-swift/27226589 # 27226589) – vrwim
Связанный: http://stackoverflow.com/questions/25175544/uiwindow-does-not-have-member-named-bounds, http://stackoverflow.com/questions/28901893/why-is- главное окно-оф-типа двойного необязательный. –