gpt4 book ai didi

objective-c - CoreData 无法完成错误

转载 作者:IT王子 更新时间:2023-10-29 07:45:48 26 4
gpt4 key购买 nike

我有一个非常烦人的问题,我似乎无法解决。

当我发送一条保存到核心数据的消息时,我有一个 View ,完成后它向数据库询问随机消息(句子)并将其保存到数据库中的另一行。

如果我对最后一部分进行硬编码,而不从数据库中获取数据,它可以正常工作,但一旦我从数据库中获取随机行,它就会变得疯狂。

在我的 AppDelegate.m 中:

- (void)save {
NSAssert(self.context != nil, @"Not initialized");
NSError *error = nil;
BOOL failed = [self.context hasChanges] && ![self.context save:&error];
NSAssert1(!failed,@"Save failed %@",[error userInfo]);
}

- (NSString*)selectRandomSentence
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Sentences" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];

NSError *error = nil;
NSUInteger count = [self.context countForFetchRequest:request error:&error];

NSUInteger offset = count - (arc4random() % count);
[request setFetchOffset:offset];
[request setFetchLimit:1];

NSArray *sentenceArray = [self.context executeFetchRequest:request error:&error];

[request release];

return [[sentenceArray objectAtIndex:0] sentence];
}

- (NSManagedObjectContext *)context {

if (_managedObjectContext != nil)
return _managedObjectContext;

NSPersistentStoreCoordinator *coordinator = [self coordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}

return _managedObjectContext;
}

在我的 ChatController.m 中:

- (void)didRecieveMessage:(NSString *)message
{
[self addMessage:message fromMe:NO];
}

#pragma mark -
#pragma mark SendControllerDelegate

- (void)didSendMessage:(NSString*)text {
[self addMessage:text fromMe:YES];
}

#pragma mark -
#pragma mark Private methods

- (void)responseReceived:(NSString*)response {
[self addMessage:response fromMe:NO];
}

- (void)addMessage:(NSString*)text fromMe:(BOOL)fromMe {
NSAssert(self.repository != nil, @"Not initialized");
Message *msg = [self.repository messageForBuddy:self.buddy];
msg.text = text;
msg.fromMe = fromMe;

if (fromMe)
{
[self.bot talkWithBot:text];
}

[self.repository asyncSave];

[self.tableView reloadData];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:[self.buddy.messages count] - 1] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

在我的 OfflineBot.m 中:

- (void)talkWithBot:(NSString *)textFromMe
{
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[self didRecieveMessage:[delegate selectRandomSentence]];
}

- (void)didRecieveMessage:(NSString *)message
{
if ([self.delegate respondsToSelector:@selector(didRecieveMessage:)])
[self.delegate didRecieveMessage:message];
}

存储库.m

- (Message*)messageForBuddy:(Buddy*)buddy {
Message *msg = [self.delegate entityForName:@"Message"];
msg.source = buddy;
[self.delegate.managedObjectContext refreshObject:buddy mergeChanges:YES];
return msg;
}

- (void)asyncSave {
[self.delegate save];
}

错误:

2012-08-10 00:28:20.526 Chat[13170:c07] * Assertion failure in -[AppDelegate save], /Users/paulp/Desktop/TestTask/Classes/AppDelegate.m:28 2012-08-10 00:28:20.527 Chat[13170:c07] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Save failed {type = immutable dict, count = 2, entries => 1 : {contents = "NSAffectedObjectsErrorKey"} = ( " (entity: Sentences; id: 0x6b8bf10 ; data: )" ) 2 : {contents = "NSUnderlyingException"} = CoreData could not fulfill a fault for '0x6b8bf10 ' }

我做错了什么?

更新我查明了这一行的错误:

NSArray *sentenceArray = [self.context executeFetchRequest:request error:&error];

当我执行该行时,出现错误...那是在获取数据时。但是,在将新数据保存到 Messages 实体时似乎出现了错误。随机句子是从句子中获取的。

在我将 asyncSave 方法更改为直接保存(因此不使用新线程)后,它保存了第一个聊天,但之后没有任何内容。它死了。

更新在我的 didFinishLaunchingWithOptions 中使用它似乎一切正常:

[self.context setRetainsRegisteredObjects:YES];

据我所知,CodeData对象模型上下文并没有释放它的对象,这似乎是添加和保存之间的问题。但是为什么?

最佳答案

嗯。您是否在 this guide 之后正确实现并发? ?您看到的问题是跨多个线程使用核心数据时的常见问题。对象在您的“后台上下文”中被删除,而另一个上下文正在访问它。在删除之后但在保存之前在后台上下文中调用 [context processPendingChanges] 可能会有所帮助。

还有一个关于优化核心数据性能的 WWDC 2010 session (137),涉及到一些删除问题。

当你执行一个 fetch 时,Core Data 会返回一个与你提供的谓词相匹配的对象集合。这些对象实际上还没有设置它们的属性值。当您访问某个属性时,Core Data 会返回到商店以“引发故障”——使用商店中的数据填充该属性。 “Could not fulfill a fault...”异常发生在 Core Data 去存储获取一个对象的属性值,但该对象不存在于持久存储中。托管对象上下文认为它应该存在,这就是它可以尝试错误的原因——这就是问题所在。导致抛出异常的上下文不知道该对象已被其他东西(如另一个上下文)从存储中删除。

注意上面的并发指南现在已经过时了,你应该使用父子上下文和私有(private)队列并发而不是旧的线程限制模型。出于多种原因,父子上下文不太可能遇到“Could not fulfill a fault...”。请提交文档错误或使用反馈表请求更新并发指南。

关于objective-c - CoreData 无法完成错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11892928/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com