If-let statement does not expand optional

I came across something in my code that seems curious, and wondered if there is a direct explanation for this behavior. Given the following statement:

if let tabBarController = topViewController as? UITabBarController { for subcontroller in tabBarController.viewControllers! { println(subcontroller.view) if let subcontrollerView = subcontroller.view { println(subcontrollerView) println(subcontrollerView!) if subcontrollerView!.window != nil && subcontroller.isViewLoaded() { topViewController = subcontroller as? UIViewController break; } } } } 

Now, as far as I know, the if-let statement should expand the conditional condition for me - but this is not the behavior shown here. I cannot access the window property of the subcontrollerView if I do not breed the option again. The x-code console returns the following:

 Optional(<UILayoutContainerView: 0x7fbccd44e7f0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fbccacdde90>; layer = <CALayer: 0x7fbccd440e30>>) Optional(<UILayoutContainerView: 0x7fbccd44e7f0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fbccacdde90>; layer = <CALayer: 0x7fbccd440e30>>) <UILayoutContainerView: 0x7fbccd44e7f0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fbccacdde90>; layer = <CALayer: 0x7fbccd440e30>> 

The expanded option and the if-let constant are the same. Why?

+6
source share
1 answer

Your AnyObject problem. (If in doubt, your problem is always AnyObject , it is an evil type that should be avoided as much as possible. The only thing worse: AnyObject? )

tabBarController.viewControllers problem that tabBarController.viewControllers returns [AnyObject]? , and optional advertising probably makes things move sideways. He probably promotes AnyObject? before AnyObject?? and then confused. This is more of a compiler error, but just the madness that comes with AnyObject . Therefore, the answer is to get rid of it as quickly as you can.

Instead of this:

 for subcontroller in tabBarController.viewControllers! { 

Do you want to:

 if let viewControllers = tabBarController.viewControllers as? [UIViewController] { for subcontroller in viewControllers { 

So the full code:

 if let tabBarController = topViewController as? UITabBarController { if let viewControllers = tabBarController.viewControllers as? [UIViewController] { for subcontroller in viewControllers { if let subcontrollerView = subcontroller.view { if subcontrollerView.window != nil && subcontroller.isViewLoaded() { topViewController = subcontroller break; } } } } } 

But we can do better. First, an optional chain is often the best way to manage multiple if-lets, and when that doesn't work, we can use the new Swift 1.2 syntax with multiple syntaxes to get this:

 if let tabBarController = topViewController as? UITabBarController, viewControllers = tabBarController.viewControllers as? [UIViewController] { for subcontroller in viewControllers { if subcontroller.view?.window != nil && subcontroller.isViewLoaded() { topViewController = subcontroller break; } } } 
+6
source

Source: https://habr.com/ru/post/982528/


All Articles