erincerol
erincerol

Reputation: 683

NSPredicate - EXC_BAD_INSTRUCTION (code= EXC_I386_INVOP, subcode=0x0)

I'm trying to read a data from CoreData with multiple NSPredicates, but I'm getting EXC_BAD_INSTRUCTION (code= EXC_I386_INVOP, subcode=0x0).

Here is the code where I try to read the data:

public class func fetchSetting(key: NSString, countryId: Int) -> Setting {
    let fetchRequest = NSFetchRequest(entityName: "Setting")

    var existingSetting: Setting?

    let keyPredicate = NSPredicate(format: "key == %@", key)
    let countryPredicate = NSPredicate(format: "countryId = %d", countryId)

    let predicate = NSCompoundPredicate(type: NSCompoundPredicateType.AndPredicateType, subpredicates: [keyPredicate!, countryPredicate!])

    fetchRequest.predicate = predicate

    if let fetchResults = CoreDataHelper().managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [Setting] {
        if (!fetchResults.isEmpty && fetchResults.count > 0) {
            println(fetchResults.first!.value)
        } else {
            existingSetting = nil
        }
    } else {
        existingSetting = nil
    }

    return existingSetting!
}

And this is how I call this function:

override func viewDidLoad() {
    super.viewDidLoad()
    textColorSetting = SettingCoreData.fetchSetting("text_color", countryId: 3)
}

The error is at keyPredicate and countryPredicate declarations. I tried key parameter as both String and NSString but I don't thing that is the issue. I'm fairly new to swift and I couldn't really figure out what is wrong here.

Upvotes: 1

Views: 1334

Answers (1)

Para
Para

Reputation: 3711

It is often the case that EXC_BAD_INSTRUCTION is due to unwrapping a variable whose value is nil.
This is exactly what happens in your code when you return existingSetting!, since existingSetting is always going to be nil in your code (you're probably missing an assignment where you wrote println(fetchResults.first!.value)).

In order to fix this, you can change the function signature to return an optional Setting:

public class func fetchSetting(key: NSString, countryId: Int) -> Setting?

Then, at the end of the function, just return existingSetting, without unwrapping it with the exclamation mark.

return existingSetting

When you invoke the fetchSetting function from viewDidLoad(), you can then test if you have a non-nil value, by using the typical Swift construct if let:

override func viewDidLoad() {
    super.viewDidLoad()
    if let textColorSetting = SettingCoreData.fetchSetting("text_color", countryId: 3) {
        // Do stuff with textColorSetting
    }
}

Upvotes: 1

Related Questions