CoreData无法解决问题 [英] CoreData could not fulfill a fault for

查看:131
本文介绍了CoreData无法解决问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a really annoying problem, which I just can't seem to get fixed.

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

I have a view when I send a message that gets saved to the Core Data, when thats done it asked the database for a random message (sentence) and saved that as well to an other row in the database.

如果我做最后一部分硬编码,没有从数据库中获取数据,它可以正常工作,但是一旦完成我从数据库中获取随机行它变得疯狂。

If I do the last part hardcoded, without fetching data from the DB, it works all fine and dandy, but as soon as I fetch the random row from the DB it goes crazy.

在我的AppDelegate.m中:

In my 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中:

In my 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中:

In 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

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 /Classes/AppDelegate.m:28 2012-08-10
00:28:20.527聊天[13170:c07] *
由于未被捕获的
异常'NSInternalInconsistencyException'而终止应用程序,原因:'保存失败
{type = immutable dict,count = 2,
entries => 1:{contents =
NSAffectedObjectsErrorKey} =(
(entity:Sentences; id: 0x6b8bf10;
数据:))2:{contents =
NSUnderlyingException} = CoreData无法解决
'0x6b8bf10
'}

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 ' }

我做错了什么?

更新
我将错误指向此行:

Update I pinpointed the error to this row:

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

当我执行该行时,我收到错误...就是在获取数据时。但是,在将新数据保存到Messages实体时,似乎会出现错误。随机句子来自句子。

When I execute that row, I get the error... that is when fetching the data. The error, however, seems to turn up when saving the new data to the Messages entity. The random sentence is fetched from Sentences.

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

After I changed the asyncSave method to saving directly (thus not using a new thread) it saves the first chat, but nothing after that. It dies.

更新
这一切似乎都可以在我的<$ c $中使用它c> didFinishLaunchingWithOptions :

[self.context setRetainsRegisteredObjects:YES];

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

I understand that hereby the CodeData Object Model Context doesn't release its objects, which seems to be the problem betweens adding and saving. But why?

推荐答案

保存核心数据对象在概念上是不可能的em>在不同的行。请记住,Core Data是一个对象图,而不是一个数据库。

It is not really conceptually possible to "save" Core Data objects "in different rows". Remember, Core Data is an object graph and not a database.

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

If you want to "relocate" your sentence, the best way is to destroy it and recreate it. If you want to keep the old instance, just create a new one and then fill in the properties from the existing one.

要销毁,请使用

[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];

如果您想阅读此内容,请查看复制并复制并粘贴 核心数据编程指南中的使用管理对象部分。

If you would like to read up on this, look at "Copying and Copy and Paste" in the "Using Managed Objects" section of the "Core Data Programming Guide".

这篇关于CoreData无法解决问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆