bobo bobo - 1 year ago 77
Swift Question

UITableview crashes when scrolling up in Swift

I am having this crash when trying to scroll up my tableview. My array is not nil. Why does it crash every time I try to scroll up? I am trying to display data from Core Data.

Here is my code:

var product = [NSManagedObject]()

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return product.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cellIdentifier = "CheckOutTableViewCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! CheckOutTableViewCell

let item = product[indexPath.row]


** It crashes here, every time I try to scroll up my table view

cell.productTitle.text = item.valueForKey("name") as! String
cell.productDescription.text = item.valueForKey("size") as! String

return cell

}

func fetch() {
let moc = DataController().managedObjectContext
let productFetch = NSFetchRequest(entityName: "Product")

do {
let fetchedResults: [NSManagedObject] = try moc.executeFetchRequest(productFetch) as! [Product]
if let results: [NSManagedObject] = fetchedResults {

product = results
print("results:\(results.count)")
}
} catch let error as NSError {
print("Error: \(error.localizedDescription)")
}
}


Product.swift

import Foundation
import CoreData


class Product: NSManagedObject {

}


Product+CoreDataProperties.swift

import Foundation
import CoreData

extension Product {

@NSManaged var id: String?
@NSManaged var name: String?
@NSManaged var img: String?
@NSManaged var quantity: String?
@NSManaged var size: String?
@NSManaged var price: String?
@NSManaged var promo: String?

}


Crash Screenshot

Answer Source

You should check the size of the array before getting your product, and use optional binding (if let) to check that the value exists in the dictionary:

if indexPath.row < product.count {
    let item = product[indexPath.row]
    if let name = item.valueForKey("name") as? String {
        cell.productTitle.text = name
    }
    if let size = item.valueForKey("size") as? String {
        cell.productDescription.text = size
    }
}

To write safer code, it's a good idea to avoid force unwrapping when possible.

In this case, given that you have a Product class for your model, you should store your products as [Product], you can then avoid using valueForKey:

if indexPath.row < product.count {
    let item = product[indexPath.row]
    if let name = item.name as? String {
        cell.productTitle.text = name
    }
    if let size = item.size as? String {
        cell.productDescription.text = size
    }
}