Francesco Zaffaroni
Francesco Zaffaroni

Reputation: 502

In which context if at all is adequate to use implicitly unwrapped optionals?

For example what I gather is that @IBoutlets are implicitly unwrapped because it wouldn't make sense for them to be nil and such event would be only caused by an error in programming, making the subsequent crash a debugging step.

But in a UIViewControllerAnimatedTransitioning could I store the ViewControllers in object properties and have them implicitly unwrapped?

class SomeTransition: NSObject, UIViewControllerAnimatedTransitioning{

  var fromVC: UIViewController!
  var toVC: UIViewController!

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

        fromVC = transitionContext.viewController(forKey: .from)
        toVC = transitionContext.viewController(forKey: .to)
    }
}

Would in this case be legitimate/good practice to use implicitly unwrapped optionals since the transition wouldn't make sense if there were not the two viewControllers to transition from/to?

As an aside, would the storing of fromVC and toVC as properties create a memory cycle?

Upvotes: 0

Views: 101

Answers (1)

ctrl freak
ctrl freak

Reputation: 12405

You are correct about implicitly-unwrapped IBOutlet optionals but apparently that doesn't go without concerns: https://cocoacasts.com/should-outlets-be-optionals-or-implicitly-unwrapped-optionals

I don't use Interface Builder so I can't speak to personal experience here.

...optionals indicate that a constant or variable is allowed to have “no value”. Sometimes it’s clear from a program’s structure that an optional will always have a value, after that value is first set. In these cases, it’s useful to remove the need to check and unwrap the optional’s value every time it’s accessed, because it can be safely assumed to have a value all of the time.

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html

But I can speak to transitioning objects and you certainly can force unwrap to- and from- view controllers in them but any kind of forced unwrapping makes some programmers nervous which is why you would most likely see a guard in animation objects:

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

    guard let fromViewController = transitionContext.viewController(forKey: .from),
        let toViewController = transitionContext.viewController(forKey: .to) else {

        return transitionContext.completeTransition(false)

    }

    ...

Sometimes objects can become bloated and traffic can become congested and everything doesn't always work all of the time as it should every time. That is why I prefer to use guards because I've experienced methods that don't always fire perfectly under stress and implicit unwrapping would have crashed the entire app whereas a guard wouldn't. Guards can also make debugging easier.

And as for creating unintended reference cycles, that is absolutely possible because I've experienced that also so if you do make the view controllers properties of the instance make them weak variables and verify that they're being deallocated.

Upvotes: 1

Related Questions