Exc_Bad_Access When Building Nspredicate

EXC_BAD_ACCESS when building nspredicate

The issue is the placeholder, not with NSPredicate directly, but with initWithFormat: that is innerly called.

%@ shouldn't be used with an int, use %d instead.

So this line:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"(alter_min_monat > %@)", months];

Should be:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"(alter_min_monat > %d)", months];

Other linked information : String Programming Guide: String Format Specifiers

Swift NSPredicate throwing EXC_BAD_ACCESS(Code=1, address=0x1) when compounding statements

The %@ placeholder in predicate format strings is for Objective-C
objects, so you have to wrap the integer into an NSNumber:

fetchRequest.predicate = NSPredicate(format: "level = %@", NSNumber(integer: level))

or use ld instead to format a (long) integer:

fetchRequest.predicate = NSPredicate(format: "level = %ld", level)

Note also that

fetchRequest.predicate = NSPredicate(format: ...)
fetchRequest.predicate = NSPredicate(format: ...)

does not create a compound predicate, the seconds assignment simply
overwrites the first. You can use an NSCompoundPredicate:

let p1 = NSPredicate(format: "level = %ld", level)!
let p2 = NSPredicate(format: "section = %ld", section)!
fetchRequest.predicate = NSCompoundPredicate.andPredicateWithSubpredicates([p1, p2])

or simply combine the predicates with "AND":

fetchRequest.predicate = NSPredicate(format: "level = %ld AND section = %ld", level, section)

NSPredicate throwing EXC_BAD_ACCESS

For two (as an example) selected items the formatString would be

"title = %@ OR title = %@"

which expects two arguments, but in

NSPredicate(format: formatString, titleCollection)

only one argument is given. You could fix that with

NSPredicate(format: formatString, argumentArray: titleCollection)

where the titleCollection now provides all arguments for the
predicate creation. But a better and simpler solution is

NSPredicate(format: "title IN %@", titleCollection)

with a fixed predicate format string.

Generally one should avoid to use string manipulation to create
predicate format strings. In this case a simple predicate serves
the same purpose. In more complicated cases, NSCompoundPredicate
can be used to build a predicate dynamically.

EXC_BAD_ACCESS when trying to build string by using %@ for an int

%@ is the format specifier for objects. An int is not an object. The format specifier for signed integers is %d or %i.

NSPredicate | Gives bad exception on Entity Fetch Request | Swift 4

This is a very common mistake.

The placeholder %@ is only for objects, for an Int32 you need %d or %i

let predicate = NSPredicate(format: "id == %d", id)

And create the fetch request with the concrete NSManagedObject subclass

let fetchRequest = NSFetchRequest<EmployeeTime>(entityName: "EmployeeTime")

this avoids the type cast later.


Your entire code can be simplified (no optionals needed):

let employTime:EmployeeTime
let context = getContext()
let fetchRequest = NSFetchRequest<EmployeeTime>(entityName: "EmployeeTime")
let predicate = NSPredicate(format: "id == %d", id)
fetchRequest.predicate = predicate
let employTimes = try! context.fetch(fetchRequest)
if let et = employTimes.first {
employTime = et
} else {
employTime = EmployeeTime(context: context)
}
return employTime

However you should avoid try!. Make your function throw and hand over a potential error to the caller.



Related Topics



Leave a reply



Submit