0

I'm writing a quiz app and there is a table view to add a subject (The name is saved to core data) and when you select an index path it passes the subject to a detail view controller (this works just fine on its own) but what I'm having trouble with is checking to see if any cards exists (the subject entity has an NSOrderedSet of "Cards"). I keep getting a crash on my two attempts, I've done this in swift before with relationships and tableViews and it's always been fine so I'm not sure what the problem is here. Thank you for the help like always!

My first attempt, although it says "catch block is unreachable because no errors are thrown in do block", it crashes with "Bad Instruction" on the line after "do"

    do {
        if let firstCard = self.subject?.cards![0] as? Card {
            self.currentCard = firstCard
        }
    } catch {


    }

My second attempt, it crashes on the first line

    if let firstCard = self.subject?.cards![0] as? Card {
        self.currentCard = firstCard
    }

My third attempt

    if self.subject!.cards != nil {

        self.currentCard = self.subject!.cards![0] as! Card
    }

My fourth attempt, unwrapping both the subject property and subject, it not rings out self.subject.cards but still crashes

    if let firstCard = self.subject!.cards?[0] as? Card {
        self.currentCard = firstCard
    }

Where the properties are declared

var draggableView = DraggableView!()
var subject : Subject?
var currentCard : Card?
var cardArray = [Card]()

The update with subject method (works perfectly, but put it here just for reference), the subject is passed from another class and this method called at the top of view did load.

func updateWithSubject(subject: Subject) {

    if let subject = self.subject {
        self.subject = subject
    }
}
Echizzle
  • 3,359
  • 5
  • 17
  • 28
  • In all four of your attempts, you do a "forced" unwrapping (`!`) at some point, which is to be generally avoided. Also, instead of explicitly trying to access index `0` in your array, you could use the `.first` (optional) property instead. If your array is empty, accessing `[0]` will yield a runtime exception. You could try `if let firstCard = self.subject?.cards?.first ...`. (Also, is `.cards` property of `Subject` class/struct not a `Card` object? Wondering about the type conversion to `Card`.) – dfrib Jan 20 '16 at 22:41
  • It says NSOrderedSet does not have a member "first", what would be the best way to convert the set to an array? – Echizzle Jan 20 '16 at 22:53
  • 1
    My bad, I thought the `.cards` property of `Subject` was a an array of `Card` objects (you haven't shown us `Subject` class/struct... But I see now that you wrote this in text). Anyway, `NSOrderedSet` has a property `.array`, _"A representation of the ordered set as an array. (read-only)"_, so I guess you could use `if let firstCard = self.subject?.cards?.array.first ...`. – dfrib Jan 20 '16 at 22:58
  • Yes that did it thank you! – Echizzle Jan 20 '16 at 23:04

2 Answers2

1

In all four of your attempts, you do a "forced" unwrapping (!) at some point, which is to be generally avoided. Also, you attempt to explicitly accessing index 0 in your NSOrderedSet; if the set is empty, accessing [0] will yield a runtime exception.

Instead, you could use the .array representation of the NSOrderedSet and use the .first (optional) property of array for a safe access test:

if let firstCard = self.subject?.cards?.array.first ...
dfrib
  • 70,367
  • 12
  • 127
  • 192
0

I think there's some awkwardness going on in your updateWithSubject method. You're checking if there's a subject already initialized before assigning to it. If that's in your viewDidLoad and only there, the assignment will never happen. The forced unwrapping that follow will surely fail after.

mango
  • 5,577
  • 4
  • 29
  • 41
  • perhaps, but when I did print(self.subject.name) in that same method it worked – Echizzle Jan 20 '16 at 22:54
  • Can we see more of your `viewDidLoad`? I'm wondering how it's called with with respect to the class passing it in. – mango Jan 20 '16 at 22:58