22

Per:

@IBOutlet weak var nameLabel: UILabel!
  1. Whenever I declare my IBOutlets, i just use var instead of weak var. But I've recently come across a few code templates that use weak var. Why do they do it? What's the added benefit?

  2. Why is there a bang operator at the end of UILabel. I know it's required and i go along w/ it, but just asking it now.

Thanks in advance.

shle2821
  • 1,856
  • 1
  • 19
  • 26
  • If these would be two questions I would have voted to close as duplicate of [Should IBOutlets be strong or weak under ARC?](http://stackoverflow.com/questions/7678469/should-iboutlets-be-strong-or-weak-under-arc?rq=1) and [What does an exclamation mark mean in the Swift language?](http://stackoverflow.com/questions/24018327/what-does-an-exclamation-mark-mean-in-the-swift-language) – Matthias Bauch Mar 12 '15 at 19:29
  • If you drag the outlet into the source this is the default behaviour of Xcode. I don't understand why it's explicitly called 'weak' or what happens at runtime when you forgot to connect the IBOutlet, but maybe because you did it by hand Apple expects you to always have set it. – Lucas van Dongen Sep 04 '15 at 13:45

4 Answers4

25
  1. Swift IBOutlet are weak by default (but others properties are strong by default). So both writing are the same.

You have more details about the difference between weak and strong here

  1. According to apple documentation

When you declare an outlet in Swift, you should make the type of the outlet an implicitly unwrapped optional (!). This way, you can let the storyboard connect the outlets at runtime, after initialization.

Community
  • 1
  • 1
Jérôme
  • 8,016
  • 4
  • 29
  • 35
12

The outlets are weak since the view elements are owned (strongly) by the view. I think it's technically OK for your view controller to have a strong reference too, but not necessary.

Weak variables are optional since they can be nil. You can declare your outlets with ? instead but that means using force-unwrapping or optional binding every time. Declaring them as implicitly-unwrapped optionals with ! is just a convenience.

gregheo
  • 4,182
  • 2
  • 23
  • 22
1

You use weak when referring to IBOutlets because so long as the object remains in its superview there will be a strong reference to it. See weak or strong for IBOutlets. Next, the bang operator indicates that the IBOutlet is an explicitly unwrapped label. With the bang operator, it guarantees that the object will exist, so when referencing it, you can simply reference it like this:

someLabel.text = "some text"

However, you can make them IBOutlets optional:

@IBOutlet weak var someLabel: UILabel?

But you must use ? when accessing them

someLabel?.text = "some text"
Community
  • 1
  • 1
Ian
  • 12,538
  • 5
  • 43
  • 62
  • 1
    Implicitly unwrapped optionals are not guaranteed to not be `nil`. However, `@IBOutlets` will be initialised when `viewDidLoad` is invoked – Petter Mar 02 '16 at 09:16
  • @Petter, `@IBOutlets` are initialised before `awakeFromNib` is called on the controller. – BangOperator Apr 08 '16 at 12:12
1
  1. @gregheo's response is the best explained, to further elaborate: if you consider ownership in this situation the View object referred to by the @IBOutlet usually shouldn't be owned by the View Controller referring to it.

    Rather it should be owned by its superview wherever it may be in the tree (which happens strongly by UIView.subviews). The View Controller instead owns the very root of it's View Tree strongly (UIViewController.view). weak explicitly declares a non-owning reference that may become nil at different points in the View Controller's life.

  2. Here I would offer an alternative to using !: using an implicitly unwrapped optional reference is a dangerous practice that weakens the tools Swift offers us. A View Controller which is loaded from Xib or Storyboard includes in its lifetime a regular time after being created and before it's View has been loaded where the @IBOutlet reference is nil, every time. To assume no one will operate on the member during that time means not using the Swift grammar and compiler's feedback to our advantage.

    Additionally @IBOutlets are a powerful tool that enables a flexible, visually focused approach when designing a screen or view. It is common practice to have your View Controller expose @IBOutlets for all information it has available, regardless of whether or not it is known that it will be used and separately deciding which to actually connect and use when building and iterating on the View from within Interface Builder.

    Additionally-additionally if your View should be flexible enough to be instantiated from Xib/Storyboard AND from code, depending on how you decide referenced subviews should be instantiated and connected they may or may not be available immediately.

For the reasons above I define mine: @IBOutlet weak var nameLabel: UILabel?

yo.ian.g
  • 1,354
  • 2
  • 14
  • 21