核心数据 VS 验证错误对象,导致崩溃
Posted
技术标签:
【中文标题】核心数据 VS 验证错误对象,导致崩溃【英文标题】:Core Data NSValidationErrorObject, causes crash 【发布时间】:2013-03-07 21:36:32 【问题描述】:我正在开发一个有用户的应用程序,每个用户都与关注者有多对多的关系。我目前在保存新用户对象时遇到了一些问题。该应用程序在managedObjectContext save
上运行。我收到以下错误:
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
[...]
我真的不知道是什么导致了这次崩溃。我的关系是这样的:
模型有一个自定义的 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;
【问题讨论】:
User->following 的关系是什么样的?看起来你设置了一些不满意的约束 它看起来和关注者一样。图片错误。 你确定你已经清理了你的应用程序和所有东西,并且你的 sqlite 文件与你定义的 xcdatamodeld 文件匹配吗?我在您提供的代码和方案中没有看到错误。 @RobinvanDijke 是的,我已经尝试删除应用程序并使用“重置内容...”,但没有区别。我认为它不起作用很奇怪。我之前使用过相同的数据模型,最近遇到了这个错误。会不会是模型外的错误造成的? 并在编译之前清理了您的 XCode 构建?我不确定,但我能想到的唯一原因是对 User->Followers 关系的限制或未清理的 sqlite。正如我所提到的,我在您提供的代码和屏幕截图中看不到错误。如果你想让我更深入地研究它,你必须提供更多可能包含错误的代码/模型数据 【参考方案1】:预感:不同MOC中的对象之间有关系吗?如果你这样做,可能会发生奇怪的事情!
【讨论】:
【参考方案2】:我在一个单独的项目中复制了您的代码和数据模型。我认为这可能是您的数据中的一个循环或其他什么,所以我尝试了以下所有代码:
[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?如果是这样,那可能会导致您的数据不一致,从而导致错误。
【讨论】:
感谢您的帮助!秘密是 ManagedObjectContext。我为该应用创建了一个共享的 ManagedObjectContext,现在它可以工作了。【参考方案3】:如果您提供有关模型定义的更多详细信息,包括User
和Followers
,将会很有帮助。这是一个猜测,但您对 followers
的反演不正确吗?
我希望看到用户定义的关系如下:
M followers User following
Follower 中的关系定义如下:
M following User followers
【讨论】:
Thaks,我其实只有一个主模型,User
,它和自己有一个多对多的关系,followers
。
我仍然认为将自己视为相反的关系是错误的。我进行了编辑,让追随者/追随者彼此相反。
见***.com/questions/12709842/…
已更改为您的建议,但我仍然收到相同的错误。但是如果我从我的保存方法中取消注释abort();
,那么它可以工作,但我会得到相同的错误日志。我已将我的保存方法添加到我原来的问题中。以上是关于核心数据 VS 验证错误对象,导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章
由于验证规则上下文导致的 iOS 核心数据保存 MOC 问题
Firestore 电话验证导致 ios 崩溃 (Flutter)
匿名上传文件对象到 Imgur API (JSON) 会导致身份验证错误 401