2

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)")
        }
    }
}
icekomo
  • 9,328
  • 7
  • 31
  • 59
  • you can set exceptional break point and see – Ashok R Jan 03 '17 at 15:46
  • I'm not sure I know how to create an exceptional break point – icekomo Jan 03 '17 at 15:51
  • your sending message to deallocated instance. thats why your app is crashing – Ashok R Jan 03 '17 at 15:53
  • Why would it become deallocated? – icekomo Jan 03 '17 at 15:55
  • You have a reference to an object that is getting deallocated. This is known as a "zombie". Those are much less common since Apple introduced ARC (which is the only option for Swift.) Do you have any variables declared as unsafe rather than weak? Normally Swift takes care of zeroing out weak references so you get a nil rather than a zombie. Post info about the declaration of your NSDecimalNumbers and how they are getting created/released. – Duncan C Jan 03 '17 at 16:26
  • The decimal is an attribute in CoreData, all I'm trying to do is fetch that entity and set the amount to a labels text. Again it works the first time I try it, and then it for some reason deallocates itself. What should I post to show that? – icekomo Jan 03 '17 at 16:39
  • @icekomo: you could show how/where you create your managed object context, and how/where you fetch the objects... – sergio Jan 03 '17 at 16:55
  • @sergio, updated, let me know if there is something else I might be able to post. – icekomo Jan 03 '17 at 17:05
  • Would like to see what's behind this: self.storeContainer.viewContext and how store container gets its' viewContext. – SpaceTrucker Jan 03 '17 at 18:09
  • @SpaceTrucker, I updated the question with the information you requested. – icekomo Jan 03 '17 at 21:54
  • 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. – Eric Hedstrom Jan 04 '17 at 19:03
  • ah ha! the name that is causing an issue is newAmount... let me to change it. – icekomo Jan 04 '17 at 19:31
  • @Eric Hedstrom, that was the problem. Thank you. If you want to put an answer below, I will give you credit for it. – icekomo Jan 04 '17 at 19:35

2 Answers2

2

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.

Eric Hedstrom
  • 1,627
  • 10
  • 13
0

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.

sergio
  • 68,819
  • 11
  • 102
  • 123
  • How could I check to see if the managed object context is being deallocated? I did enable Zombie Objects, didn't help much, just telling me the NSDecimal object is deallocated. – icekomo Jan 03 '17 at 21:53
  • Doesn't it tell you also where the `NSDecimalNumber` is being deallocated? Any useful stack traces? About the MOC being deallocated, you should inspect your code to understand that -- maybe you are creating a second MOC and assigning it to the same reference -- also, try to log its address to see if it changes... – sergio Jan 04 '17 at 07:45