2

I have a UITableViewController loading its entries from Core Data via a NSFetchedResultsController. Like this:

let historyItem = fetchedResults.objectAtIndexPath(indexPath) as HistoryItem

historyItem has a title property defined like this:

@NSManaged var title: String

So in cellForRowAtIndexPath the code says

cell?.textLabel?.text = historyItem.title

and that should all be fine. title is not an optional and does not need unwrapping.

However, in the past, the stored Core Data has acquired some objects where the value of the title property is nil. They are there stored, waiting to cause errors. If one of these objects is displayed in a cell, I will see a runtime address exception on the above Swift code line, where the address is 0.

For robustness, I need to write code to make sure the stored data delivered to my program does not cause crashes. However, I cannot write

if historyItem.title == nil { } // gives compiler error

because title is not an optional and the compiler will not let me. If I write

let optionalTitle:String? = historyItem.title

I still get a runtime EXC_BAD_ACCESS on that line.

How can I check that title is not erroneously nil?

Thanks!

emrys57
  • 6,679
  • 3
  • 39
  • 49
  • I have closed as a duplicate because I think it is the same problem. Let me know if those solutions do not apply in your case, then I will reopen the question. – Martin R Mar 13 '15 at 10:57
  • Yes, that is exactly the same case (which I failed to find with my searches), but the high-marked solution there does not work. I will ask another question pointing that out. Thanks! – emrys57 Mar 13 '15 at 11:04
  • I asked another question at http://stackoverflow.com/questions/29031080/swift-detecting-an-unexpected-nil-value-in-a-non-optional-at-runtime-casting-a – emrys57 Mar 13 '15 at 11:30

3 Answers3

0

Since you have nil values, the title property should be optional and you should declare it as optional in your core data model and in your NSManagedObject historyItem class.

Nikos M.
  • 13,685
  • 4
  • 47
  • 61
  • If I just change the type of title to String?, (and change all the places where title is used through the code, to unwrap it) then the core data code gives runtime errors. I could write a migrator, maybe... but I'd much rather just check for the unexpected nil value. – emrys57 Mar 13 '15 at 10:44
0

When I do this in editor I dont get an error so might be the answer:

let a = ""

if a as String? == nil {
        println("Nil")
    }
    else {
        println("Not nil")
    }
Arbitur
  • 38,684
  • 22
  • 91
  • 128
  • Looks promising! Unfortunately, it doesn't work. If I write `if historyItem.title as String? == nil { t = "was Nil" }` then I get EXC_BAD_ACCESS if title is nil. – emrys57 Mar 13 '15 at 10:50
  • Try ```if let historyItemTitle = historyItem.title as? String { "historyItem.title not nil" } else { "historyItem.tile is nil" }``` – pJes2 Mar 13 '15 at 10:56
  • Or if you make that title of type :String! this will enable nil comparison. – Arbitur Mar 13 '15 at 11:19
0

@NSManaged var title: String should be @NSManaged var title: String? if there is possibility for a nil value. Then, you cannot go wrong with optional binding:

if let historyItemTitle = historyItem.title {
  cell?.textLabel?.text = historyItemTitle
} else {
  cell?.textLabel?.text = "Title missing"
}
pJes2
  • 623
  • 1
  • 8
  • 13