1

Check out the following code.

class MyViewCell: UICollectionViewCell {
    @IBOutlet weak var title: UILabel!

    override init(frame: CGRect) {
        super.init(frame: frame)
        didLoad()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        didLoad()
    }

    /// Common init code.
    func didLoad() {
        self.title = UILabel()
        self.title.textColor = .white
        ...
    }
}

My app crashes at self.title.textColor = .white with the following error:

fatal error: unexpectedly found nil while unwrapping an Optional value

Any idea why UILabel() returns nil?

Mick F
  • 7,312
  • 6
  • 51
  • 98

2 Answers2

3

You're assigning something directly to a weak reference, and at that point there are no strong owning references so the weak reference is immediately removed. When you then access it on the next line, you're hitting a nil !, which causes your crash.

You need to create a local variable which will keep the label in scope until something else retains it, for example you add it to a view:

func didLoad() {
    let label = UILabel()
    // Configure the label...
    self.view.addSubview(label)
    // A view retains its subviews, so now you can assign to the weak reference
    self.title = label

}

However, if your variable really is an outlet that is configured in the storyboard, then you shouldn't really be populating it in init with coder, since it will then get overwritten with whatever the storyboard holds for the outlet.

jrturton
  • 118,105
  • 32
  • 252
  • 268
-1

Make sure your IBOutlet is connected on your storyboard/xib

You dont also need this line

 self.title = UILabel()
dhin
  • 460
  • 5
  • 12
  • 1
    The line that you say isn't needed lies at the heart of the question. You're assuming that the OP has created a label in a storyboard, but that's not the case. *Given that* the line in question assigns a label to `self.title`, why is `self.title` nil on the next line? jrturton's answer covers this. – Caleb Sep 18 '17 at 14:12
  • @Caleb okay my answer is wrong but IBOutlets are used if he is using an interface builder. so I didnt assume. Its the correct implementation. pls check apple documentations and this thread: https://stackoverflow.com/a/1643039/6298923, https://developer.apple.com/library/content/documentation/General/Conceptual/Devpedia-CocoaApp/Outlet.html – dhin Sep 19 '17 at 07:26
  • I'm familiar with outlets. Marking a property `@IBOutlet` makes it available in Interface Builder, but it doesn't mean you must connect the property in IB or that you can't set it by some other means. I can certainly see why the `@IBOutlet` made you think first of storyboard problems, but the answer to the OP's question really lies in the next qualifier: `weak`. – Caleb Sep 19 '17 at 14:26