2013-03-07 135 views
3

我正在开发一个应用程序,我有用户,每个用户都有跟随者的多对多关系。我目前在保存新用户对象时遇到了一些问题。该应用程序在managedObjectContext save上分割。我收到以下错误:核心数据NSValidationErrorObject,导致崩溃

Unresolved error Error Domain=NSCocoaErrorDomain Code=1560 "The operation couldn’t be completed. (Cocoa error 1560.)" UserInfo=0x8580640 {NSDetailedErrors=(
"Error Domain=NSCocoaErrorDomain Code=1550 \"The operation couldn\U2019t be completed. (Cocoa error 1550.)\" UserInfo=0x85820c0 {NSValidationErrorObject=<User: 0x7575870> (entity: User; id: 0x75757c0 

NSValidationErrorKey=followers, NSLocalizedDescription=The operation couldn\U2019t be completed. (Cocoa error 1550.), NSValidationErrorValue=Relationship 'followers' on managed object (0x7575870) <User: 0x7575870> (entity: User; id: 0x75757c0 
"Error Domain=NSCocoaErrorDomain Code=1550 \"The operation couldn\U2019t be completed. (Cocoa error 1550.)\" UserInfo=0x8586830 {NSValidationErrorObject=<User: 0x7571ec0> (entity: User; id: 0x7571f00 

"Error Domain=NSCocoaErrorDomain Code=1550 \"The operation couldn\U2019t be completed. (Cocoa error 1550.)\" UserInfo=0x858e820 {NSValidationErrorObject=<User: 0x7573120> (entity: User; id: 0x7573160 

[...] 

我无法真正弄清楚是什么导致了这个崩溃。我的关系是这样的:

enter image description here

enter image description here

该模型有一个自定义NSManagedObject子类与@property (nonatomic, retain) NSSet *followers;。正如我所说,我不确定是什么造成了这一点,所以任何指导或想法都会很棒!

更新

该方法的应用程序崩溃:

- (void)saveContext 
{ 
    NSError *error = nil; 
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext; 
    [managedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 
    if (managedObjectContext != nil) { 
     if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { 
      // Replace this implementation with code to handle the error appropriately. 
      // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      // Uncomment "abort" makes it work, but I still get the error. 
      abort(); 
     } 
    } 
} 

更新2

更多来自我的模型代码,以及如何使用它们:

如何我设置我的获取请求控制器:

- (NSSortDescriptor *)sortDescriptorForFetchRequest 
{ 
    NSSortDescriptor *sortDescriptor; 
    if ([self.postType isEqualToString:@"following"] || [self.postType isEqualToString:@"followers"]) { 
     sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"userId" ascending:NO]; 
    } else { 
     sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"postId" ascending:NO]; 
    } 

    return sortDescriptor; 
} 

- (NSEntityDescription *)entityForFetchRequest 
{ 
    NSEntityDescription *entity; 
    if ([self.postType isEqualToString:@"followers"] || [self.postType isEqualToString:@"following"]) { 
     entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:[self.appController managedObjectContext]]; 
    } else { 
     entity = [NSEntityDescription entityForName:@"Post" inManagedObjectContext:[self.appController managedObjectContext]]; 
     } 

    return entity; 
} 

- (void)setUpFetchResultController 
{ 
    if (self.fetchedResultsController == nil) { 
     NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
     [fetchRequest setEntity:[self entityForFetchRequest]]; 
     [fetchRequest setPredicate:[self predicateBasedOnPostType:self.postType]]; 
     NSArray *sortDescriptors = @[[self sortDescriptorForFetchRequest]]; 
     [fetchRequest setSortDescriptors:sortDescriptors]; 

     self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self.appController managedObjectContext] sectionNameKeyPath:nil cacheName:[self cacheName]]; 
     self.fetchedResultsController.delegate = self; 
    } 
} 

而且我的模型,User

+ (void)addUserFromDictionary:(NSDictionary *)dictionary forUser:(User *)user inManagedObjectContext:(NSManagedObjectContext*)moc follower:(BOOL)follower following: (BOOL)following 
{ 
    User *localUser; 
    if (follower) { 
     if ([dictionary isKindOfClass:[NSArray class]]) { 
      NSEnumerator *enumerator = [dictionary objectEnumerator]; 
      id value; 
      while (value = [enumerator nextObject]) { 
       localUser = [self parseUserFromDictionary:value inManagedObjectContext:moc]; 

       if ([self user:localUser alreadyFollowingUser:user inManagedObjectContext:moc] == NO) { 
        [user addFollowersObject:localUser]; 
        [localUser addFollowingObject:user]; 
       } 
      } 
     } 
    } 
} 

+ (User *)parseUserFromDictionary:(NSDictionary *)dictionary inManagedObjectContext:(NSManagedObjectContext*)moc 
{ 
    NSNumberFormatter *numberFormatter= [[NSNumberFormatter alloc] init]; 
    NSNumber * userId = [numberFormatter numberFromString:(NSString *)[dictionary valueForKey:@"id"]]; 

    User *user; 

    if ([self userAlreadyExist:userId inManagedObjectContext:moc] == NO) { 
     NSEntityDescription *userDescription = [NSEntityDescription entityForName:@"User" inManagedObjectContext:moc]; 
     user = [[User alloc] initWithEntity:userDescription insertIntoManagedObjectContext:moc]; 
    } else { 
     user = [User findUser:userId inManagedObjectContext:moc]; 
    } 

    user.name = [dictionary valueForKey:@"name"]; 
    [...]  
    return user; 
} 
+0

User->跟随样子的关系是什么?它看起来像你设置了一些不满足的约束 – 2013-03-07 21:40:53

+0

它看起来跟追随者一样。错误的图片。 – Anders 2013-03-09 08:51:01

+0

你确定你已经清除了你的应用程序和一切,并且你的sqlite文件与你定义的xcdatamodeld文件相匹配吗?我没有看到您提供的代码和方案中的错误。 – 2013-03-11 08:11:44

回答

4

在预感:不同的MOC中的对象之间的关系?奇怪的事情可能发生,如果你这样做!

1

将是有益的,如果你给的模型定义的详细信息,包括UserFollowers。这是一个猜测,但followers不正确吗?

我希望看到在用户的关系定义如下:

M followers User following 

和追随者的关系定义如下:

M following User followers 
+0

Thaks,我其实只有一个主要模型,'用户''与自己有多对多的关系,'追随者'。 – Anders 2013-03-09 22:24:54

+0

我仍然认为一个关系本身就是一个逆过程是错误的。我做了一个编辑,让追随者/追随者彼此反转。 – XJones 2013-03-09 23:12:15

+0

请参阅http://stackoverflow.com/questions/12709842/ios-coredata-inverse-relationships-to-itself – XJones 2013-03-09 23:12:40

3

我复制你的代码和数据模型在一个单独的项目。我认为这可能是你的数据什么的一个周期,所以我尝试了所有的如下代码:

[userA addFollowersObject:userB]; 
[userB addFollowingObject:userA]; 

[userB addFollowersObject:userA]; 
[userA addFollowingObject:userB]; 

[userA addFollowersObject:userA]; 
[userA addFollowingObject:userA]; 

[userB addFollowingObject:userB]; 
[userB addFollowersObject:userB]; 

...但节省是有效的所有时间。我能想到的最后一件事是多线程。你是否正在使用多个线程访问ManagedObjectContext?如果是这样,那可能会导致导致错误的数据不一致。

+0

感谢您的帮助!秘密是ManagedObjectContext。我为应用程序创建了一个共享的ManagedObjectContext,现在它可以工作。 – Anders 2013-03-16 16:09:23