Search code examples
iosswiftuitableviewiboutlet

Is a UITableViewCell and its outlets initialized after `dequeueReusableCellWithIdentifier`?


Is it save to access an outlet of a custom UITableViewCell right after instantiating it with dequeueReusableCellWithIdentifier?

E.g.

class MyCell: UITableViewCell {

    @IBOutlet weak var myImageView: UIImageView!
    var image: UIImage?

    override func awakeFromNib() {
        update()
    }        

    func update() {
        myImageView.image = image
    }
}

class MyViewController: UIView() {
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("MyCellIdentifier") as! MyCell
        cell.image = UIImage(...)
        cell.update()
    }
}

I have used this implementation a lot but very rarely (<0.001%) I get a crash report pointing to line myImageView.image = image.

UPDATE: So far the crashes have been observed only for one specific implementation where 1 outlet is linked to many UIImageView() in custom cells because they share the same class.


Solution

  • The simple method dequeueReusableCellWithIdentifier: returns an optional which is not safe.

    Use this method instead which is safe because it returns an non-optional cell

    let cell = tableView.dequeueReusableCellWithIdentifier("MyCellIdentifier",
               forIndexPath: indexPath) as! MyCell
    

    Since the image property of an UIImageView object can be nil it's recommended to declare related UIImage properties as optional (?) rather than implicit unwrapped optional (!) without the default initializer (())