Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c CoreData无法实现的故障_Objective C_Ios_Core Data_Nsmanagedobject_Nsmanagedobjectcontext - Fatal编程技术网

Objective c CoreData无法实现的故障

Objective c CoreData无法实现的故障,objective-c,ios,core-data,nsmanagedobject,nsmanagedobjectcontext,Objective C,Ios,Core Data,Nsmanagedobject,Nsmanagedobjectcontext,我有一个很烦人的问题,我似乎无法解决 当我发送一条保存到核心数据的消息时,我有一个视图,当它发送到核心数据时,它向数据库请求一条随机消息(句子),并将其保存到数据库中的另一行 如果我做最后一部分硬编码,而不从数据库中获取数据,它工作得很好,但一旦我从数据库中获取随机行,它就会变得疯狂 在my AppDelegate.m中: - (void)save { NSAssert(self.context != nil, @"Not initialized"); NSError *erro

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

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

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

在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;
}
在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中:

- (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/Classes/AppDelegate.m:28 2012-08-10 00:28:20.527聊天[13170:c07]*由于未捕获而终止应用程序 异常“NSInternalInconsistencyException”,原因:“保存失败” {type=immutable dict,count=2, 条目=>1:{contents= “NSAffectedObjectsErrorKey”}=( “(实体:句子;id:0x6b8bf10; 数据:”)2:{内容= “NSUnderlyingException”}=CoreData无法实现的错误 '0x6b8bf10 “}

我做错了什么

更新 我指出了这一行的错误:

NSArray *sentenceArray = [self.context executeFetchRequest:request error:&error];
当我执行该行时,我得到错误。。。这是在获取数据时发生的。但是,在将新数据保存到Messages实体时,似乎会出现错误。随机句子是从句子中提取出来的

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

更新 在my
didFinishLaunchingWithOptions
中使用此选项似乎一切都正常:

[self.context setRetainsRegisteredObjects:YES];

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

从概念上讲,不可能将核心数据对象“保存在不同的行中”。请记住,核心数据是对象图,而不是数据库

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

为了破坏,使用

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

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

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

还有一个关于优化核心数据性能的WWDC 2010会议(137),该会议有一点深入

执行fetch时,核心数据返回与您提供的谓词匹配的对象集合。这些对象实际上尚未设置其属性值。当您访问某个属性时,核心数据返回存储以“触发故障”——使用存储中的数据填充该属性。“无法实现错误…”当核心数据进入存储以获取对象的属性值,但该对象在持久存储中不存在时,会发生异常。托管对象上下文认为它应该存在,这就是为什么它可以尝试该错误的原因——这就是问题所在。导致引发异常的上下文不知道该对象已被其他内容(如另一个上下文)从存储中删除


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

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

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

您可以在第一次调用中添加预回迁,以避免延迟加载,我相信问题会得到解决

这是我们可以对请求执行预取的方式:

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

希望能有所帮助。

我通过将NSFetchedResultsController的“cacheName”字符串更改为nil修复了错误

NSFetchedResultsController*aFetchedResultsController= [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil
cacheName:@“Root”nil]

Paul,在您的更新中,您提到您将错误精确定位到
executeFetchRequest
call,但您的错误发生在保存上下文时,这没有意义。有没有可能在应用程序中使用多个线程?这通常是导致
nsinternalinconsistenceexception
self.context和self.managedObjectContext之间的区别的罪魁祸首。您似乎在交替使用它们,这听起来不是一个好主意。此外,您似乎没有使用ARC,但看起来您没有正确管理内存。此错误通常意味着您从存储中删除了一些内容,但没有正确更新MOC,或者您有多个线程正在处理同一个MOC。Self.context只是我的AppDelegate中的一个方法。我已经分析并检查了我的代码,但没有内存泄漏。我怎样才能确保我在s上