Fault:CoreData无法满足的错误

关于Fault的问题,在to a fault中经常遇到, 我有一个非常烦人的问题,我似乎无法修复。

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

当我发送一条保存到核心数据的消息时,我有一个视图,当它完成时,它要求数据库提供一个随机消息(句子)并将其保存到数据库中的另一行。

如果我做最后一部分硬编码,没有从数据库获取数据,它工作得很好,,但是一旦我从数据库中获取随机行,它就会变得疯狂。

在我的 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];
}

在 My 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];
}

Repository.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 聊天 [13170:c07]* 在-[AppDelegate save],/ Users / paulp / Desktop / TestTask / Cl / AppDelegate.m:28 2012-08-10 00:28:20.527 聊天 [13170:c07] *由于未捕获的异常类型“NSON

我做错了什么?

更新我将错误定位到此行:

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

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

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

更新这一切似乎在我的didFinishLaunchingWithOptions中使用这个:

[self.context setRetainsRegisteredObjects:YES];

我明白,特此 CodeData 对象模型上下文不释放其对象,这似乎是添加和保存之间的问题。

66

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

还有一个关于优化核心数据性能的 WWDC 2010 会话(137)进入删除位。

当你执行一个 fetch Core Data 返回一个与你提供的谓词匹配的对象的集合。这些对象实际上还没有设置它们的属性值。当你访问一个属性时,Core Data 回到存储以“触发错误”-用存储中的数据填充属性。当 Core Data 去存储以获取对象的属性值时,会发生“无法履行错误...”异常,但对象不存在于持久存储中。

请注意,上述并发指南现在已经过时,您应该使用父子上下文和私有队列并发,而不是旧的线程限制模型。父子上下文不太可能遇到“无法履行错误...”,原因有很多。请提交文档错误或使用反馈表单请求更新并发指南。

6

从概念上讲,“save”Core Data objects“in different rows”是不可能的。请记住,Core Data 是一个对象图,而不是一个数据库。

如果你想“重新定位”你的句子,最好的方法是销毁它并重新创建它,如果你想保留旧的实例,只需创建一个新的,然后从现有的填充属性。

销毁时,使用

[self.context deleteObject:sentenceObject];

要重新创建,请使用

Sentence *newSentence = [NSEntityDescription insertNewObjectForEntityForName:
  "Sentences" inManagedObjectContext:self.context];
newSentence.sentence = sentenceObject.sentence;
// fill in other properties, then
[self.context save:error];

如果您想了解这一点,请查看“核心数据编程指南”的“使用托管对象”部分中的“Copying and Copy and Paste”。

1

检查核心数据机制。“。故障会减少应用程序消耗的内存量。故障是占位符对象表示尚未完全实现的托管对象,或者是表示关系的集合对象:”

0

发生这种情况是因为您在完成获取第一个调用的所有关系之前将“随机消息”添加到新行。

您可以添加一个预取到您的第一个调用,以避免延迟加载和问题将得到解决,我相信。

这是我们如何为请求进行预取:

[request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObjects:@"whatEverOfYourWillNumberOne",@"whatEverOfYourWillNumberTwo", nil]];

希望有帮助。

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(771)
Lamb ic:ic_launcher代表什么
上一篇
Cloud怎么念:google云平台sku描述链接实例怎么计费:
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(35条)