CoreData NSManagedObject 已损坏

Posted

技术标签:

【中文标题】CoreData NSManagedObject 已损坏【英文标题】:CoreData NSManagedObject being corrupted 【发布时间】:2013-02-23 02:30:06 【问题描述】:

我有一个控制器,它是工作流的根。如果工作流没有数据对象,那么我创建一个新的,如果有,我使用现有的。我有一个模型对象的属性(一个 NSManagedObject)

@property (nonatomic, retain) Round *currentRound;

每当显示相应的视图时,我都会调用以下命令

self.currentRound = [self.service findActiveRound];
if (!self.currentRound) 
    NSLog((@"configure for new round"));
    self.currentRound = [self.service createNewRound];
    ...
 else 
    NSLog(@"configure for continue");
    // bad data here        

问题出在上面标记的地方,有时数据对象已损坏。在我没有展示的部分中,我在一些文本字段上设置了值来表示模型中的值。有时没问题,但最终模型对象上的属性是空的,事情就坏了

在调试器中,对回合的引用似乎没有改变,但 NSLogging 相关属性显示它们无效。调试似乎延迟了损坏的发生。

我知道我没有保存上下文...这有关系吗?如果是这样,为什么我第一次回到这个控制器时它并不总是失败?

我的 findActiveRound 消息没什么特别的,但以防万一

-(Round *) findActiveRound

    NSLog(@"Create Active Round");
    NSFetchRequest *request = [[NSFetchRequest alloc]init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Round" inManagedObjectContext:context];
    [request setEntity:entity];

    NSPredicate *pred = [NSPredicate predicateWithFormat:@"isComplete == %@", [NSNumber numberWithBool:NO]];
    [request setPredicate:pred];

    NSError *error = nil;
    NSArray *results = [context executeFetchRequest:request error:&error];

    if ([results count] == 0) 
        return nil;
     else 
        return [results objectAtIndex:0];
    

非常感谢。

编辑回复

我所说的损坏是指当我尝试从模型对象中获取一些简单的字符串属性时,我得到 nil 值。所以在上面的代码中(我想我有一个回合)我做了类似的事情

self.roundName.text = self.currentRound.venue;
self.teeSelection.text = self.currentRound.tees;

并且看不到我输入的数据。由于它只是有时会失败,但最终总是会失败,所以我会在它消失之前看到我输入的数据。

我很确定上下文是相同的。我的服务是单例的,并且是这样创建的

@implementation HscService

+(id) getInstance

    static HscService *singleton = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^
        singleton = [[self alloc] init];
    );
    return singleton;


-(id) init

    if (self = [super init]) 
        model = [NSManagedObjectModel mergedModelFromBundles:nil];
        NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];

        NSString *path = [self itemArchivePath];
        NSURL *storeUrl = [NSURL fileURLWithPath:path];

        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithBool:YES],
                                 NSMigratePersistentStoresAutomaticallyOption,
                                 [NSNumber numberWithBool:YES],
                                 NSInferMappingModelAutomaticallyOption, nil];

        NSError *error = nil;
        if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) 
            [NSException raise:@"Open failed" format: @"Reason: %@", [error localizedDescription]];
        

        context = [[NSManagedObjectContext alloc] init];
        [context setPersistentStoreCoordinator:psc];
        [context setUndoManager:nil];
    
    return self;


-(NSString *) itemArchivePath

    NSArray *docDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *dir = [docDirectories objectAtIndex:0];
    return [dir stringByAppendingPathComponent:@"hsc1.data"];

在每个控制器中,我都得到了单例来执行操作。我计划围绕轮次操作定义一个委托,并在我的 AppDelegate 中实现它,所以我只在应用程序中获得一次服务,但现在认为这不重要....

【问题讨论】:

【参考方案1】:

您确定数据实际上已损坏吗?托管对象上下文非常高效,在调试器中出现故障是正常的。来自文档:

“故障是 Core Data 用来减少你的 应用程序的内存使用..."

见http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdFaultingUniquing.html

如果数据确实丢失并且无法通过其他方法访问,请确保您使用相同的托管对象上下文来访问数据。如果数据尚未提交到数据存储,则不会在 MOC 之间“同步”。

【讨论】:

感谢您的评论。我用更多细节更新了我的问题。我也可以在过渡之前尝试保存每个控制器......但我想了解这一点的根源...... 实际问题是我正在创建该对象的另一个实例。所以问题出在我身上。

以上是关于CoreData NSManagedObject 已损坏的主要内容,如果未能解决你的问题,请参考以下文章

CoreData:将字符串转换为 NSManagedObject 实例

SWIFT CoreData NSManagedObject

保持 CoreData NSManagedObject 新鲜

如何在 CoreData 的代码中设置 NSManagedObject 与另一个 NSManagedObject 或它们的堆栈的关系?

调用 NSManagedObject 类上的指定初始化程序失败 - CoreData

CoreData:NSManagedObject 不响应用户定义的消息