Thread 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

I have the error - Thread 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0), i'm trying to use Firebase, so to show the message I'm using a table view controller and I get that error

that's my code:


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
        let label1 = cell?.viewWithTag(1) as! UILabel //that's the line of the error
        label1.text = messages[indexPath.row].messageBody
      
        return cell!
    }

Replies

In the context of Swift code,

EXC_BAD_INSTRUCTION
usually means you’ve hit a compiler trap, that is, an undefined instruction inserted into the code by the compiler because of a bug detected at runtime. The most common cause of these are:
  • failure to unwrap an optional — This can be a forced unwrap (

    !
    ) or an implicit unwrap (accessing an implicitly unwrapped optional that’s nil).
  • array out of bounds

  • a failed forced cast (

    as!
    ), either because the value was a nil optional or because the value was of the wrong type

Line 3 in your snippet is doing a bunch of different things, all of which might cause this trap:

  • if

    cell
    is nil,
    cell?.viewWithTag(1)
    will be nil and the forced cast will fail
  • if there’s no view with tag 1,

    viewWithTag(_:)
    will return nil and the forced cast will fail
  • if the view with tag 1 leads to something other than a UILabel, the forced cast will fail

If you split the code up into separate lines you can tease these apart and find the problem.

I also recommend that you change your style a little. Within your code snippet

cell
really can’t be nil. If it is, you’ll trap at the unforced unwrap when you return (line 6 in your snippet). If you’re going to trap anyway, you might as well trap early, so you could write this:
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
let label1 = cell.viewWithTag(1) as! UILabel //that's the line of the error
label1.text = messages[indexPath.row].messageBody
return cell

Note how by adding the forced unwrap on line 1, you get rid of one on line 4 and get rid of the

?
on line 3. Better.

Even better you could write this:

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

where UIKit guarantees to not give you back nil.

When dealing with optionals, your goạl should be to limit the scope of those optionals as much as possible. That way you only have to unwrap once, so you can only fail in one place, which makes all your other code simpler.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
  • Is there anytime when

    DispatchQueue.main.sync { // code }

    is run, that doesn't cause a one of these errors also? I get the exact message when I run that code even when I don't put any code in the execution block:

    Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
Add a Comment