pablisco pablisco - 8 days ago 10
Objective-C Question

Some CoreData relationships are lost after closing app

This is the overview of my problem:

I am adding (and confirm they are added) about 1400 relationships loaded from a soap service into CoreDat. After I close the app and open it again some of the relationships are lost; I only see around 800 of them (although it varies). Also, I am not getting any errors.

And now, more details:

I have an object called

User
that has information about services a user have saved; it looks something like this:



@interface OosUser : NSManagedObject

+ (OosUser *) userFromSlug: (NSString *) slug;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *slug;
@property (nonatomic, retain) NSMutableSet /* Service */ *services;
- (void) addServicesObject: (Service * )service;
- (void) removeServicesObject: (Service *) service;

@end

@implementation User

@dynamic name;
@dynamic slug;
@dynamic services;

static NSString *fetchPredicate = @"slug = %@";

+ (User *) userFromSlug:(NSString *)slug
{
User *result = [super objectWithPredicate: fetchPredicate, slug];
if (!result) {
result = [super create];
result.slug = slug;
}
return result;
}

@end


In the part of the code where the data is used, the relationships are saved like this:

NSMutableSet *userServices = self.user.services;

for (Service *service in servicesToAdd) {
[self.services addObject: service];
bool contained = false;
for (Service *userService in userServices) {
if ((contained = [userService.slug isEqualToString:service.slug])) {
break;
}
}
if (!contained) {
// [userServices addObject:service];
[self.user addServicesObject: service];
NSError *error = nil;
if (![[service managedObjectContext] save:&error]) {
NSLog(@"Saving failed");
NSLog(@"Error: %@", [error localizedDescription]);
}else {
NSLog(@"Registered service %d: %@", self.services.count, service.slug);
}
}
}


The case is that I have checked with the debugger and I can see that all the over 1400 relationships are added, but when the app is reset and they are restored though self.user.services I only get around 800 objects.

Why could this be happening? Anybody had this before?

Thanks in advance.




UPDATE:

People keep suggesting that I am not using Core Data correctly but the problem is that the data is lost AFTER restarting the app. There is absolutely no problem with it while using it. I am using Core Data as correct as it could be given the limited documentation and examples you get from Apple.

Answer
NSMutableSet *userServices = self.user.services;

...

            [userServices addObject:service];

Can't do that. self.user.services does not return a mutable set. That's what that addServicesObject method is for. Change the second line to:

            [self.user addServicesObject:service];

From Apple documentation:

It is important to understand the difference between the values returned by the dot accessor and by mutableSetValueForKey:. mutableSetValueForKey: returns a mutable proxy object. If you mutate its contents, it will emit the appropriate key-value observing (KVO) change notifications for the relationship. The dot accessor simply returns a set. If you manipulate the set as shown in this code fragment:

[aDepartment.employees addObject:newEmployee]; // do not do this! then KVO change notifications are not emitted and the inverse relationship is not updated correctly.

Recall that the dot simply invokes the accessor method, so for the same reasons:

[[aDepartment employees] addObject:newEmployee]; // do not do this, either!