user30646 user30646 - 2 months ago 11
iOS Question

NSPredicate throwing EXC_BAD_ACCESS

I'm trying to delete books that user selected and I'm getting EXC_BAD_ACCESS at NSPredicate line. Can anyone tell me where am I doing wrong?

func deleteSelectedBook() {
// Create Fetch Request
let fetchRequest = NSFetchRequest(entityName: "BookEntity")

// Create array string for predicate
var titleCollection:[String] = []
var formatString:String = ""
if let selectedCellCollection = self.tableView.indexPathsForSelectedRows {
for index in selectedCellCollection{
if (!formatString.isEmpty) {
formatString += " OR "
}
var temp = (self.tableView.cellForRowAtIndexPath(index)?.textLabel?.text)!
titleCollection.append(temp)
formatString += " title = %@ "
}
}

// Configure Fetch Request
fetchRequest.predicate = NSPredicate(format: formatString, titleCollection)

......

Answer

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.