关闭应用后,某些CoreData关系会丢失

pab*_*sco 9 iphone persistence core-data objective-c

这是我的问题的概述:

我正在添加(并确认它们已添加)大约1400个从soap服务加载到CoreDat的关系.关闭应用程序并再次打开它之后,一些关系就会丢失; 我只看到他们中的大约800个(虽然它有所不同).另外,我没有收到任何错误.

现在,更多细节:

我有一个名为的对象User,它有关于用户保存的服务的信息; 它看起来像这样:

@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
Run Code Online (Sandbox Code Playgroud)

在使用数据的代码部分中,关系保存如下:

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);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

情况是我已经检查过调试器,我可以看到所有1400多个关系都被添加了,但是当应用程序被重置并通过self.user.services恢复时我只能获得大约800个对象.

为什么会发生这种情况?以前有人这个吗?

提前致谢.


更新:

人们一直建议我没有正确使用Core Data,但问题是重启应用程序后数据丢失了.使用它时绝对没有问题.我使用核心数据是正确的,因为它可以提供有限的文档和从Apple获得的示例.

mor*_*tar 12

NSMutableSet *userServices = self.user.services;

...

            [userServices addObject:service];
Run Code Online (Sandbox Code Playgroud)

不能这样做.self.user.services不返回可变集.这就是那种addServicesObject方法的用途.将第二行更改为:

            [self.user addServicesObject:service];
Run Code Online (Sandbox Code Playgroud)

来自Apple文档:

了解点访问器返回的值与之间的差异非常重要mutableSetValueForKey:.mutableSetValueForKey:返回一个可变的代理对象.如果改变其内容,它将为关系发出适当的键值观察(KVO)更改通知.点访问器只返回一个集合.如果您操作此代码片段中显示的集合:

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

回想一下,dot只是调用了访问器方法,所以出于同样的原因:

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

  • 你可以带马到水......参见上面添加的文件."它有时很有效,所以很明显我做得对,"这不是好逻辑.将某些内容转换为错误的类型将调用未定义的行为,因此它可能正常工作,因为谁知道原因.您声明了该属性,因此您可以将其声明为NSMutableSet,但该属性的动态_definition_不会返回该属性,因此您会误导编译器.或者它可能返回一个NSMutableSet但不是实际修改持久数据的那个.既然它不起作用,你可以__try__记录正确的方法吗? (5认同)
  • 我在需要时所做的就是实现一个`mutableServices`方法,该方法返回`[self mutableSetValueForKeyPath:@"user.services"]`并且可行.简单地投射是******并且导致**未定义的**行为. (2认同)