0

在导航控制器中,我从视图控制器 1 转到视图控制器 2。

View Controller 1 是一个绑定到 FetchedResultsController 的表视图控制器。它从特定的上下文中获取数据并显示它。然后,如果点击了一行,我会继续查看控制器 2。在 segueing 时,我使用视图控制器 1 中的数据设置了视图控制器 2 的特定 NSManagedObject 属性。

现在,在视图控制器 2 中,我可以使用 NSManagedObject 属性显示数据,然后对其进行更改并执行保存:。当我返回查看控制器 1 时,会反映更改。但是,如果我重新启动应用程序,它不会再反映在任何视图控制器中。

这就是我进行保存的方式。

- (void)hiddenAttributeSwitchSlid:(UISwitch *)sender
{
    [self.workoutType.managedObjectContext performBlock:^{
        self.workoutType.workoutHiddenByDefault = [NSNumber numberWithBool:sender.isOn];
        NSError *error = nil;
        if (![self.workoutType.managedObjectContext save:&error]) {
            NSLog(@"There was an error in saving to context - %@", [error localizedDescription]);
        }
        else {
            NSLog(@"No error");
        }
    }];
}

FitnessType 是一个 NSManagedObject,它在 prepareForSegue: 中设置,然后再转到这个视图控制器。

即使我不使用 performBlock:,它也不起作用。

PS - 我知道以前有人问过这类问题。我浏览了它们,但似乎没有任何效果。

4

4 回答 4

2

您是否在模型中为该属性设置了默认值?

Core Data 中有一个已识别的错误,在某些情况下(我没有一直缩小范围),在应用程序的后台处理期间,具有默认值的属性会被重置几次。

对此进行测试的方法是侦听通过 KVO 更改的值并记录更改,然后复制您的测试。如果您看到一些更改,那么您就知道您遇到了该错误。

我见过的唯一可靠的已知解决方案是删除默认值。如果需要默认值,那么我会将其添加到方法中的NSManagedObject子类中-awakeFromInsert,然后更新验证方法以检查它。糟透了我知道。

更新#2

你有多少上下文?

您是否使用父子上下文?

如果是这样,您是否正在保存最顶层的父母?

更新#3

好的,a里面UIManagedDocument有两个NSManagedObjectContext实例。您使用 a 有什么原因UIManagedDocument吗?您的申请中是否有多个文件?如果您不这样做,那么我强烈建议您切换回传统的 Core Data 堆栈。UIManagedDocument并不是真的要在单个堆栈应用程序中。

至于直接保存的问题,UIManagedDocument在退出应用程序时尝试在后台保存。如果可能需要一些时间,而且个人而言,不是很可靠。您可以在退出时请求保存,这将有助于确保保存速度很快,但即便如此,它也可能不可靠。

你是如何退出应用程序的?

你在 Xcode 中杀死它吗?

你是在后台处理它然后恢复它吗?

你是在后台处理它,然后从 iOS 设备上杀死它吗?

您可以侦听UIManagedDocument要保存的内容,然后打印一条日志语句,这样您就可以查看保存实际发生在磁盘上的时间。这可能有助于缩小准确的范围,何时保存和不保存。

于 2012-05-10T22:11:13.620 回答
1

我认为你不应该在上下文中使用保存,文档会自动保存。

保存文档时可能会出现数据一致性错误。我建议您不要使用保存上下文的[self.workoutType.managedObjectContext save:&error]方法,而是使用以下继承自该类的类,该类UIManagedDocument会在自动保存时添加日志记录:

LoggingManagedDocument.h:

@interface LoggingManagedDocument : UIManagedDocument

@end

LoggingManagedDocument.m:

#import "LoggingManagedDocument.h"

@implementation LoggingManagedDocument

- (id)contentsForType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
    NSLog(@"Auto-Saving Document");
    return [super contentsForType:typeName error:outError];
}

- (void)handleError:(NSError *)error userInteractionPermitted:(BOOL)userInteractionPermitted
{
    NSLog(@"error: %@ userInfo: %@", error, error.userInfo);
}

@end

此类应该可以帮助您识别问题,为什么您的数据没有保存。更改属性后,让应用程序运行并等待 15-30 秒,然后自动保存就会发生。

日志记录基于:http: //blog.stevex.net/2011/12/uimanageddocument-autosave-troubleshooting/

于 2012-05-11T19:52:10.900 回答
0

从 UIManageDocument 文档:

UIManagedDocument 架构有几个考虑因素:

您通常应该使用标准的 UIDocument 方法来保存文档。如果您直接保存子上下文,您只会将更改提交到父上下文而不是文档存储。如果您直接保存父上下文,您将回避文档执行的其他重要操作。

最简单的选择是使用无保存模型,这意味着使用文档的 NSUndoManager。我通常会

[self.workoutType.managedObjectContext.undoManager beginUndoGrouping];
在添加更改之前
[self.workoutType.managedObjectContext.undoManager endUndoGrouping];
编辑后。

于 2012-05-11T17:05:36.247 回答
0

您需要保存文档:

[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
于 2015-03-11T03:29:22.183 回答