[NSDecimalNumber retain]: message sent to deallocated instance 0x174222220, but why?

528 views Asked by At

I seem to be getting this error.

*** -[NSDecimalNumber retain]: message sent to deallocated instance 0x174222220

The first time I run the app, the code executes fine, but if I got back to that VC, the app crashes with the message above. I did some research and I think it means that some how that NSDecimal is being released. It's very odd, as I have 3 other decimals all set up the exact same way that are working.

The decimals are being stored in Core Data, and then being set to a label in my VC in side the cellForIndexAt method.

print("\(historyEntry.newAmount) new amount")

The very first time I get back the correct amount. But the second time or if I try move the tableview the app crashes with the message above. What would cause the decimal to release itself?

EDIT

I have a CoreDataStack swift file and the managedContext is being created like this:

    lazy var managedContext: NSManagedObjectContext = {
    return self.storeContainer.viewContext
}()

I am fetching the object like this:

  // load the data
    let fetchRequest: NSFetchRequest<Statement> = Statement.fetchRequest()
    fetchRequest.predicate = NSPredicate(format:"person.name == %@ AND amountOwed >= 0", personName)

    let sort = NSSortDescriptor(key: #keyPath(Statement.amountOwed), ascending: true)
    fetchRequest.sortDescriptors = [sort]
    positiveFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: coreDataStack.managedContext, sectionNameKeyPath: nil, cacheName: nil)

    do{
        try positiveFetchedResultsController.performFetch()
    }catch let error as NSError{
        print("Fetching error: \(error), \(error.userInfo)")
    }
    positiveFetchedResultsController.delegate = self

I think pass the fetched object that I am using to another ViewController and access its properties like this:

print("\(historyEntry.changeAmount) change amount") // gives me back the correct amount that was saved evrytime.

This attribute however crashes after the first time

print("\(historyEntry.newAmount) new amount") // first time correct, after that error message from above.

EDIT

Here is the CoreDataStack class

    import Foundation
import CoreData

class CoreDataStack {

    private let modelName: String

    init(modelName: String) {
        self.modelName = modelName
    }

    lazy var managedContext: NSManagedObjectContext = {
        return self.storeContainer.viewContext
    }()

    private lazy var storeContainer: NSPersistentContainer = {

        let container = NSPersistentContainer(name: self.modelName)
        container.loadPersistentStores { (storeDescription, error) in
            if let error = error as NSError? {
                print("Unresolved error \(error), \(error.userInfo)")
            }
        }
        return container
    }()

    func saveContext () {
        guard managedContext.hasChanges else { return }

        do {
            try managedContext.save()
        } catch {
            let nserror = error as NSError
            print("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}
2

There are 2 answers

0
Eric Hedstrom On BEST ANSWER

What are the names of your NSDecimalNumber properties? If any of the property names start with "new", that will confuse ARC and lead to problems like this.

To quote from Apple's Introduction to ARC,

You cannot give an accessor a name that begins with new. This in turn means that you can’t, for example, declare a property whose name begins with new unless you specify a different getter.

2
sergio On

I would try and make sure that the managed object context is not being deallocated and reallocated when you reenter your VC. That could explain why your MOCs are deallocated.

Other than that, I would enable "Zombie Objects" under Product/Scheme/Edit Scheme/Run/Diagnostics and see if that provides some more hints.