27
votes

I am getting an EXC-BAD-ACCESS error on this statement:

var thisPredicate = NSPredicate(format: "(sectionNumber == %@"), thisSection)

thisSection has an Int value of 1 and displays the value 1 when I hover over it. But in the debug area I see this:

thisPredicate = (_ContiguousArrayStorage ...)

Another predicate using a String shows as ObjectiveC.NSObject Why is this happening?

3
You have an extra opening parenthesis that should not be there - Paul.s
I'm not sure why it shows an extra parenthesis above because that is not what I have - which is: var thisPredicate = NSPredicate(format: "(sectionNumber == %@)",thisSection) - PatriciaW
@PatriciaW the problem in your question was then that you missed the closure parenthesis after @. Btw, I have edited my previous answer, maybe you should take a look into some considerations I have added. - Hugo Alonso
Hugo, I corrected my code in the comment above but I did not edit it ... which I will do now. - PatriciaW

3 Answers

35
votes

You will need to change %@ for %i and remove the extra parenthesis:

Main problem here is that you are putting an Int where it's expecting an String.

Here's an example based on this post:

class Person: NSObject {
    let firstName: String
    let lastName: String
    let age: Int

    init(firstName: String, lastName: String, age: Int) {
        self.firstName = firstName
        self.lastName = lastName
        self.age = age
    }

    override var description: String {
        return "\(firstName) \(lastName)"
    }
}

let alice = Person(firstName: "Alice", lastName: "Smith", age: 24)
let bob = Person(firstName: "Bob", lastName: "Jones", age: 27)
let charlie = Person(firstName: "Charlie", lastName: "Smith", age: 33)
let quentin = Person(firstName: "Quentin", lastName: "Alberts", age: 31)
let people = [alice, bob, charlie, quentin]


let thisSection = 33
let thisPredicate = NSPredicate(format: "age == %i", thisSection)

let _people = (people as NSArray).filteredArrayUsingPredicate(thisPredicate)
_people

Another workaround would be to make thisSection's value an String, this can be achieved by String Interpolation or via description property of the Int.. lets say:

Changing:

let thisPredicate = NSPredicate(format: "age == %i", thisSection)

for

let thisPredicate = NSPredicate(format: "age == %@", thisSection.description)

or

let thisPredicate = NSPredicate(format: "age == %@", "\(thisSection)")

of course, you can always bypass this step and go for something more hardcoded (but also correct) as:

let thisPredicate = NSPredicate(format: "sectionNumber == \(thisSection)")

But take into account that for some weird reason String Interpolation (this kind of structure: "\(thisSection)") where leading to retain cycles as stated here

34
votes

When your data is safe or sanitized, you might try String Interpolation Swift Standard Library Reference. That would look something like this:

let thisSection = 1
let thisPredicate = NSPredicate(format: "sectionNumber == \(thisSection)")
1
votes

On 64 bit architecture an Int maps to an Int64 and %i will overflow if its value is greater than 2,147,483,648.

You will need to change %@ for %ld and remove the extra parenthesis.