1

I am in the process of transitioning over to Swift from Obj-C and I think I have a fairly good understanding of the ? ! concepts. I am however experiencing a bad access crash on a field that is nil.

I am using

var cell :ContactIInfoTableViewCell!

cell = tableView.dequeueReusableCellWithIdentifier("notes", forIndexPath: indexPath) as! ContactIInfoTableViewCell
            if let clinic = receivedVisitDetails?.clinicNotes {
                cell.textLabel?.text = clinic
            }

Which produces the error if empty. My understanding was that the IF statement would stop this issue but it hasn't.

What am I doing wrong here?

enter image description here

UPDATE

This is a detail view for the core data fetch.

NSManagedObject is set as

var receivedVisitDetails: VisitDetails! = nil

The prepareForSeague on the previous view

let visits:VisitDetails = fetchedResultsController.objectAtIndexPath(indexPath!) as! VisitDetails
            taskController.receivedVisitDetails = visits

The crash only happens when the clinicNotes is null.

Allreadyhome
  • 1,252
  • 2
  • 25
  • 46
  • Could you also post the crash log? – Antonio Jul 10 '15 at 10:44
  • Added a snippet above – Allreadyhome Jul 10 '15 at 10:51
  • can you show the code where receivedVisitDetails is set? – GoatInTheMachine Jul 10 '15 at 10:53
  • Nit pick (not crash related) - no need to use `ContactIInfoTableViewCell!`, I mean `!`, because `dequeueReusableCellWithIdentifier(_:forIndexPath:)` always returns valid `UITableViewCell`, check documentation for this method. Return type is `UITableViewCell`. – zrzka Jul 10 '15 at 10:54
  • Does the error happen when `receivedVisitDetails` is nil, or when its `clinicNotes` property is? – Antonio Jul 10 '15 at 10:57
  • Thanks for the comment @robertvojta. Anotonio this only happens when clinicNotes is nil. Though technically reveivedVisitDetails should never be nill. – Allreadyhome Jul 10 '15 at 11:04
  • Is `clinicNotes` an implicitly unwrapped optional? – Antonio Jul 10 '15 at 11:06
  • @Antonio . Honestly I'm not too sure. Maybe I do need to read up on this more. My understanding if its not unwrapped then it can be nil? The NSMangedOject is set as `@NSManaged var clinicNotes: String` – Allreadyhome Jul 10 '15 at 11:34
  • @Allreadyhome ok it's not an implicit unwrapped. It could be something related to coredata, but I can't help on that. Unrelated suggestion: avoid implicitly/forced unwrapping, unless you are 101% sure of what you're doing. Use non optionals, if possible, otherwise normal optionals. – Antonio Jul 10 '15 at 11:40
  • 1
    Hmm, when I read all your updates / edits, shouldn't be your `clinitNotes` type `String?` instead of `String` if it's optional in your Core Data model? – zrzka Jul 10 '15 at 12:05
  • Thanks for the help from both @Antonio and @robertvojta.... Robert you were right that the issue was the lack of `String?` in the core data managed object. Surprising this isn't generated by Xcode when they create the class. Live and learn I guess! – Allreadyhome Jul 10 '15 at 12:32
  • @robertvojta I suggest you to rewrite that comment as n answer, so that it can be chosen as the solution - just to make it clear how the problem has been solved – Antonio Jul 10 '15 at 12:35
  • I agree. Submit and I will mark it up as correct – Allreadyhome Jul 10 '15 at 12:36
  • Done. You're welcome, glad it's fixed now. – zrzka Jul 10 '15 at 12:54

2 Answers2

1

After all edits and comments, the problem is in:

@NSManaged var clinicNotes: String

It's optional in your Core Data model, but not in your class. Should be changed to:

@NSManaged var clinicNotes: String?

Here's similar problem where Imanou suggests mogenerator, which can handle it for you. It automatically generates two classes for each managed object. Human part is suitable for editing (not touched by mogenerator when updating your model) and machine is not suitable for editing (rewritten every time you do update your model). Human part inherits from machine part.

Whenever I'm working with Core Data I do use it. I strongly suggest it as well. You can also add it to build phase, so, it automatically update your machine classes when you're building your project.

Community
  • 1
  • 1
zrzka
  • 20,249
  • 5
  • 47
  • 73
-1

When using this construction, you don't have to use ? as it is unwrapped for you.

try

if let clinic = receivedVisitDetails.clinicNotes {
            cell.textLabel?.text = clinic
        }
Kelo
  • 453
  • 1
  • 3
  • 17
  • Nope, if `receivedVisitDetails` is optional there must be `?` even in `let` construct ... Or you'll get _Value of optional type not unwrapped ..._ – zrzka Jul 10 '15 at 10:47
  • My bad, I was mixing up two things. Sorry – Kelo Jul 10 '15 at 11:12