Pablo DelaCruz
Pablo DelaCruz

Reputation: 1

Getting a EXC_BAD_ACCESS when trying to initialize my custom Cell in TableViewController

My application fetches data from a mock API. Using a custom cell, I display the names of authors on my landing page viewController. When I click on a cell, it takes that author's book information to display on a 2nd TableViewController. But even though the implementation is the same as for the landing page. My app freezes until I get a EXC_BAD_ACCESS error

It seems like it's stuck in an infinite loop, but without a proper error, it's hard to know why.

Infinite Loop?

I can get this to work without using a custom cell, but then I cannot display all the information I want (only book title or release date), so the data is there.

import UIKit

class BooksTableViewCell: UITableViewCell {

    @IBOutlet weak var name: UILabel!
    @IBOutlet weak var pages: UILabel!
    @IBOutlet weak var release: UILabel!
//    @IBOutlet var coverImage: UIImageView!

    static let cellIdentifier = "BooksTableViewCell"
//
    override func awakeFromNib() {
        super.awakeFromNib()
    }

    static func nib() -> UINib {
        return UINib(nibName: "BooksTableViewCell", bundle: nil)
    }

    //MARK: configure
    public func configure(with viewModel: BooksCellViewModel) {
        name.text = viewModel.name
        pages.text = String(viewModel.pages)
        release.text = viewModel.release
//        coverImage.image = viewModel.image
    }

}
import UIKit

class BooksTableViewController: UITableViewController {
    
    var books: [Book] = []
    var authorName: String = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(BooksTableViewCell.nib(), forCellReuseIdentifier: BooksTableViewCell.cellIdentifier)
        tableView.delegate = self
        tableView.dataSource = self
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return authorName
    }

    // MARK: - Table view data source
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return books.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print("Hello1")
        let cell = tableView.dequeueReusableCell(withIdentifier: BooksTableViewCell.cellIdentifier, for: indexPath) as! BooksTableViewCell
        print("Hello2")
        let model = books[indexPath.row]
        cell.configure(with: BooksCellViewModel(name: model.title, pages: model.pages, release: model.releaseDate))
        
        return cell
    }
}

The landing page controller and cell is similar but works with no problems

import UIKit

class LandingTableViewController: UITableViewController {
    let parser = DataAPI()
    var authors = [Author]()
    var books = [Book]()
    var authorName = ""

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(AuthorTableViewCell.nib(), forCellReuseIdentifier: AuthorTableViewCell.cellIdentifier)
        tableView.delegate = self
        tableView.dataSource = self

        parser.getData {
            data in
            self.authors = data

            //Reload UI on Main thread:
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }
    }
    
    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "List of Authors"
    }
    // MARK: - Table view data source
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return authors.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: AuthorTableViewCell.cellIdentifier, for: indexPath) as! AuthorTableViewCell
        let model = authors[indexPath.row]
        cell.configure(with: AuthorCellViewModel(name: model.authorName))
        
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        books = authors[indexPath.row].books
        authorName = authors[indexPath.row].authorName
        performSegue(withIdentifier: "Show Books", sender: nil)
    }
    
    // MARK: - Navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.

        if (segue.identifier == "Show Books") {
            let showBooksViewController: BooksTableViewController = segue.destination as! BooksTableViewController
            showBooksViewController.books = books
            showBooksViewController.authorName = authorName
        }
    }
}

Upvotes: 0

Views: 198

Answers (1)

Pablo DelaCruz
Pablo DelaCruz

Reputation: 1

I was able to fix the issue by correctly naming my variables. I needed to be using releaseDate not release as per my model object.

Upvotes: 0

Related Questions