Core Data attribute changes to nil (ARC related?)
Asked Answered
R

3

10

I have some Core Data functionality that was working fine until some recent (seemingly unrelated) changes were made. Now I'm getting problems where all the attributes belonging to a particular NSManagedObject subclass instance are suddenly returning nil.

Let's say my NSManagedObject subclass is called Foo and it has only one attribute called value. Once I realised value was somehow becoming nil I went and setup the following category to monitor changes to value.

@implementation Foo (Debug)

- (void)setValue:(NSDate *)value
{
    [self willChangeValueForKey:@"value"];
    [self setPrimitiveValue:value forKey:@"value"];     
    [self didChangeValueForKey:@"value"];
}

- (NSDate *)value
{
    [self willAccessValueForKey:@"value"];
    NSDate *value = [self primitiveValueForKey:@"value"];
    [self didAccessValueForKey:@"value"];

    return value;
}

@end

setValue: is called for my object and the argument passed in is a non-nil NSDate. Then the value is retrieved (in another method). The same value that was specified is retrieved correctly.

However when another method tries to read value, the value accessor is called and a nil value is returned by primitiveValueForKey:.

In between the two reads setValue: is not called and the Foo object itself is still valid (non-nil). In fact no other Core Data operations are performed between the two reads on any Core Data object or the context as a whole.

We're using ARC in our project. Is it possible ARC is somehow messing with my Core Data variables and deallocating them? If so does anybody have any suggestions for debugging ARC deallocations? Or better yet, does anyone know a way to ensure ARC doesn't deallocate my variable.

This may not even be ARC related, however I'm at a bit of a loss as to what is going on. Any suggestions would be very much appreciated.

Riot answered 26/8, 2011 at 1:27 Comment(3)
ARC is still under NDA so we can't discuss it outside Apple's restricted forums.Miscellanea
ARC is not under NDA.Zeringue
Any chance you're working on two different threads with two different copies of the object? Otherwise, are you sure this is the exact same object? That you aren't making two? Or that you haven't reset your context or otherwise lost your changes in between?Rb
B
16

This is very likely because the NSManagedObjectContext that these objects belong to, is going away. When you have NSManagedObject instances around but you're not holding on to the context yourself, those managed objects will start returning nil.

Under ARC, make sure you store the context in a strong variable, i.e. an instance variable that's not weak or a static global.

Non-ARC, i.e. retain-release code, make sure you're retaining the context.

Barrada answered 28/12, 2011 at 15:35 Comment(8)
Does anyone know why this happens? I had the same problem and could only solve it by using my own managedObjectContext variable. But this is annoying and sounds more like a bug.Merrygoround
You need to hold onto the context. That's not a bug. The managed object context makes most of Core Data work. If you don't have a context, the managed objects don't know what to interact with.Barrada
Using an ivar NSManagedObjectContext *mContext wouldn't do the job?Merrygoround
You can store the context into an instance variable of the app delegate, yes.Barrada
Sorry for being a little bit inaccuracy. I declare mContext in the interface of class A which is kind of NSManagedObject. But the object of class A loses its context and the context allocated and assigned to mContext directly after returning the object. All other attributes or properties keep their values. Only the context disapears.Merrygoround
I'm not sure what you're doing. Perhaps you should create a new question and show how you're implementing A. You're saying that A is a subclass of NSManagedObject and you're storing the context as an ivar of A? That's not good.Barrada
Insteed of an ivar, how should I store the context to avoid losing it? See more details here, please. Examples are welcome ;)Merrygoround
FWIW - thanks from the future for saving me hours of further banging of my head against the wall.Keverne
S
2

As others mentioned (it was my case also), be sure that you haven't reset your managed object context because if you do, all Entities stored as properties will have data: <fault>.

If you do reset your managed object context, you will also have to re-fetch the Entity itself.

Sharlenesharline answered 25/7, 2018 at 11:31 Comment(0)
P
0

check the viewDidLoad-Method

profile = [NSEntityDescription insertNewObjectForEntityForName:@"MyProfile" inManagedObjectContext:profileContext];

hope this works

Poco answered 1/11, 2011 at 13:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.