2013-03-07 173 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