user3662992
user3662992

Reputation: 688

Swift : thread 1 exc_bad_instruction (code=exc_i386_invop subcode=0x0) in tableview

I'm using Tableview controller to make two prototype cells that app crash due to

thread 1 exc_bad_instruction (code=exc_i386_invop subcode=0x0) pointed to >>> return cell! in the first cell

fatal error: unexpectedly found nil while unwrapping an Optional value

   override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return 10
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if (indexPath.section == 0) {
        let cell = tableView.dequeueReusableCellWithIdentifier("one", forIndexPath: indexPath) as? one
         cell?.textLabel?.text = "book"
        return cell!
    } else {

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

        cell.textLabel?.text = "not a book"
        return cell

    }

enter image description here

Upvotes: 1

Views: 2284

Answers (3)

J.Arji
J.Arji

Reputation: 661

I think you should edit code :

 override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return 2
    }

Upvotes: 0

BaseZen
BaseZen

Reputation: 8718

If I may improve the code:

 let cellID = (indexPath.section == 0) ? "one" : "two"
 if let cell = tableView.dequeueReusableCellWithIdentifier(cellID, forIndexPath: indexPath)
        as? UITableViewCell
     cell.textLabel!.text = (cellID == "one") ? "book" : "not a book"
     return cell
 } 
 else {
     assertionFailure("Unable to dequeue a cell of ID \(cellID)")
     return nil
 }

Then you'll get sensible error behavior. I'll bet that, even though you've named your classes one and two, that you have neglected to set their 'Identifier' within StoryBoard in the Attributes Inspector for each cell prototype.

Your answer is very wrong. You should not be creating lots of table cells. This is a misuse of tables. You should only use the ones on the reuse queue.

Use my version of the code, and set a breakpoint just after the if let cell. Analyze the object in the debugger and see what type it really is.

If instead you hit the assertionFailure, you still haven't really set the Identifier properly in StoryBoard. Show us a screen capture to convince us.

Upvotes: 2

Sam Clewlow
Sam Clewlow

Reputation: 4351

Looks like it's because the call

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

is doing a forced down cast of the cell to type two, and the object returned is not of type two. Using ! here is basically saying:

"Dequeue a cell (returns type AnyObject) and then downcast it two type two. I know down casts can fail if the type doesn't match, but in this case I'm sure it will. No need to handle errors"

As casts can fail, the cast returns an optional. In this case the cell returned can't be downcast as the types don't match. Check the code that registers the identifier "two", and check you are registering the right type of class (A UITableViewCell subclass named two)

Upvotes: 1

Related Questions