0

I'm accessing a variable in one of my functions that got passed from a few other functions, but when it reaches the line where I use it in this final function, I get a EXC_ACCESS_ERROR, however I can inspect the value in the debugger and confirm it has a value.

From the top, I'll show the stack of function call:

First, inside my ViewController, there is a CoreData Model variable

var expense : Expense?

*it gets assigned a value in the previous viewController

Then, in the same ViewController, I call the first function:

TimekeeperClient.sharedInstance().getExpenseAttachments(expenseID: expense.tkID) { (success, statusCode) in
   //Do some work
}

Inside getExpenseAttachments, the code is as follows and I call the next function:

func getExpenseAttachments(expenseID: Int64,completion completionHandlerForAttachments: @escaping (_ success: Bool, _ statusCode: Int?) -> Void)
{
    let url = Methods.getExpenseAttachmentsListUrl(expenseID: Int(expenseID))
    Alamofire.request(url, headers: getHeaders()).responseArray { (response : DataResponse<[AttachmentResponse]>) in
        guard let attachmentsResponse = response.result.value else
        {
            print("Could not map attachments from server response")
            completionHandlerForAttachments(response.result.isSuccess, response.response?.statusCode)
            return
        }

        let attachmentsToSync = AttachmentRepository.getUnsyncedExpenseAttachments(expenseID: expenseID,tkExpenseAttachmentList: attachmentsResponse)

        //Do some other stuff
        }
    }
}

IMPORTANT: note that the expenseID value passed in from the previous function does have a value when the line let url = Methods.getExpenseAttachmentsListUrl(expenseID: Int(expenseID)) is executed.

Then, the next the final function call (and where the problem is) is AttachmentRepository.getUnsyncedExpenseAttachments(.... This function has the following body:

static func getUnsyncedExpenseAttachments(expenseID: Int64, tkExpenseAttachmentList: [AttachmentResponse]) -> [AttachmentResponse] {

    var attachmentResponse:[AttachmentResponse] = [AttachmentResponse]()

    //Get Core Data Attachment List
    let attachmentRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Attachment")
    let sortDescriptor = NSSortDescriptor(key: "name", ascending: false)
    let predicate = NSPredicate(format: "expense.tkID == %@", expenseID)
    attachmentRequest.sortDescriptors = [sortDescriptor]
    attachmentRequest.predicate = predicate

    //Do some CoreData Stuff
}

The app crashes with the EXC_ACCESS_ERROR on the line let predicate = NSPredicate(format: "expense.tkID == %@", expenseID) when trying to access the expenseID variable. What is strange is if I hover over the variable, I can see xcode showing the expected value of "15543".

What am I missing?

Pratik Shah
  • 563
  • 4
  • 14
Marnus Steyn
  • 1,053
  • 2
  • 16
  • 44
  • You could try to give predicate using string interpolation in swift or try to replace %@ with %i. Perhaps this could help: https://stackoverflow.com/questions/31884863/swift-how-do-i-create-a-predicate-with-an-int-value – Rishabh Apr 23 '18 at 08:47
  • Don't use "%@" for an `Int64`, you should use `%llu`. – Larme Apr 23 '18 at 08:47
  • Possible duplicate of [EXC\_BAD\_ACCESS when building nspredicate](https://stackoverflow.com/questions/23610509/exc-bad-access-when-building-nspredicate) – Larme Apr 23 '18 at 08:54
  • Thank you @Larme, that fixed it! I'm still confused why I threw the Access Error and didn't give me a more relatable NSPredicate error. – Marnus Steyn Apr 23 '18 at 08:56
  • That will happen in Objective-C with `UInt64 myInt = 64; NSLog(@"MyInt: %@", myInt);`, it's related to `stringWithFormat:` used logic, and it doesn't check the type and the placeholder and just "replace" them directly potentially causing a crash. So in Swift, it should be similar. – Larme Apr 23 '18 at 08:58

1 Answers1

0

Thanks to Larme I now no that the problem was simply with the syntax of my NSPredicate Statement - Changing it from expense.tkID == %@ to expense.tkID == %llu fixed it.

I was however confused over the Access Error, As I though the expenseID was unreachable, but the access error occurred somewhere inside of NSPredicate.

Marnus Steyn
  • 1,053
  • 2
  • 16
  • 44