NSManagedObject 不保存

Posted

技术标签:

【中文标题】NSManagedObject 不保存【英文标题】:NSManagedObject not saving 【发布时间】:2011-09-06 14:13:47 【问题描述】:

抱歉,如果之前已经回答过这个问题,但我找不到参考。我第一次尝试 Cocoa / obj-c。我正在尝试开发一个应用程序,该应用程序将通过 http(a la s3)与远程备份系统同步,并且在一些基本的核心数据问题上遇到了挫折。

我创建了一个实体,可以毫无问题地调用它。当我在 NSManagedObjectContext 上调用 save 时,问题就来了。

我不会包含调用对象上下文/模型所涉及的所有方法,因为日志输出应该(我认为)验证它是否按预期工作。

最好用代码和适当的日志条目来描述。


*首先,为了说明,我正在调用托管对象:*

- (NSManagedObjectModel *)managedObjectModel 

    if (managedObjectModel != nil) 
        return managedObjectModel;
    

    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    NSLog(@"The managed object model is defined as follows:\n%@",     managedObjectModel);
    return managedObjectModel;

以及上面 NSLog 的日志输出:

2011-09-06 14:31:38.322 TryAgain[18885:a0f] The managed object model is defined as follows:
(<NSManagedObjectModel: 0x2000e2b00>) isEditable 1, entities 
        BackupItinerary = "(<NSEntityDescription: 0x20020e9e0>) name BackupItinerary, managedObjectClassName NSManagedObject, renamingIdentifier 
            BackupItinerary, isAbstract 0, superentity name (null), properties \n    \"file_url\" = \"(<NSAttributeDescription: 0x2000faec0>), name
            file_url, isOptional 0, isTransient 0, entity BackupItinerary, renamingIdentifier file_url, validation predicates (\\n), warnings (\\n),
            versionHashModifier (null), attributeType 700 , attributeValueClassName NSString, defaultValue (null)\";\n    \"last_sync_date\" =
            \"(<NSAttributeDescription: 0x2000faf60>), name last_sync_date, isOptional 1, isTransient 0, entity BackupItinerary, renamingIdentifier
            last_sync_date, validation predicates (\\n), warnings (\\n), versionHashModifier (null), attributeType 900 , attributeValueClassName
            NSDate, defaultValue (null)\";\n, subentities \n, userInfo \n, versionHashModifier (null)";
, fetch request templates 

这看起来很成功。没有抛出异常或警告。

现在,当我在对象上下文上调用 save 时,实际问题就来了。我有一个 NSOpenPanel,它允许选择要备份的 dir / 文件(全部连接并且工作正常)。在用户选择一个目录/文件后,我想设置该值,所以我:

NSArray *paths = [panel URLs];
NSURL *filePath = [paths objectAtIndex:0];
[directories addObject:filePath];
[directories setArray:[[NSSet setWithArray: directories] allObjects]];  
NSEntityDescription *BackupItineraryEntity = [[self.managedObjectModel  entitiesByName] objectForKey:@"BackupItinerary"];
NSManagedObject* BackupItinerary = [[NSManagedObject alloc]
                    initWithEntity:BackupItineraryEntity
    insertIntoManagedObjectContext:self.managedObjectContext];
[BackupItinerary setValue:[filePath absoluteString] forKey:@"file_url"];
NSLog(@"entity:\n%@", BackupItinerary);

对 NSLog 的调用显示(已选择 /Users/rick/selenium2-webdriver/):

2011-09-06 14:31:38.328 TryAgain[18885:a0f] entity:
<NSManagedObject: 0x200216c80> (entity: BackupItinerary; id: 0x200090860 <x-coredata:///BackupItinerary/t0C005B39-D185-454B-B364-31314EEB10F02> ;     
        data: 
            "file_url" = "file://localhost/Users/rick/selenium2-webdriver/";
            "last_sync_date" = nil;
        )

那么,file_url 似乎已被填充,是吗?但是当我:

NSError *error;
if (![[self managedObjectContext] save:&error]) 
    NSLog(@"Unresolved error %@, %@, %@", error, [error userInfo],[error localizedDescription]);

日志说:

2011-09-06 14:31:38.330 TryAgain[18885:a0f] Unresolved error Error Domain=NSCocoaErrorDomain Code=1570 UserInfo=0x2000cc4e0 "file_url is a required  
value.", 
    NSLocalizedDescription = "file_url is a required value.";
    NSValidationErrorKey = "file_url";
    NSValidationErrorObject = "<NSManagedObject: 0x20020f660> (entity: BackupItinerary; id: 0x20008faa0 <x-coredata:///BackupItinerary/t0C005B39
            D185-454B-B364-31314EEB10F03> ; data: \n    \"file_url\" = nil;\n    \"last_sync_date\" = nil;\n)";
, file_url is a required value.

所以基本上:

似乎(?)我可以调用实体并为其设置一个值,但是在保存它时未设置值。上面的代码是内联执行的,我正在使用垃圾回收。

感觉像是一个完全的新手学生错误问题,但对于我的生活,我看不到我在阅读文档、高级教程和示例代码后缺少什么。

感谢指点!

【问题讨论】:

【参考方案1】:

您正在查看两个不同的托管对象实例。设置了file_url 属性的实例是&lt;NSManagedObject: 0x200216c80&gt;,而报告错误的实例是&lt;NSManagedObject: 0x20020f660&gt;

在某个地方,您正在插入一个实例,但没有给它一个 file_url 值。在给出的代码中,如果用户在 NSOpenPanel 中选择取消,则可能会发生这种情况。

【讨论】:

好的,关于对象 ID 的指针很好 - 谢谢。这对我来说有点新,但很有趣!与用户单击取消无关,因为上面的代码包含在检测 NSOKButton 的 if 块中。但是,在尝试填充存储目录列表时,我正在以另一种方法更改 BackupItinerary 的范围。【参考方案2】:

从您的 NSLog 的输出来看,我会说 BackupItinerary 对象在保存上下文时是不同的。在不同的场合检查这个输出:

插入和设置值时:

entity:
<NSManagedObject: 0x200216c80>

保存时:

NSValidationErrorObject = "<NSManagedObject: 0x20020f660>

您可以看到实例的地址不同,因此您要插入一个,但保存另一个实例。希望这会有所帮助。

【讨论】:

以上是关于NSManagedObject 不保存的主要内容,如果未能解决你的问题,请参考以下文章

NSManagedObject 不保存

神奇的记录 NSFetchedResultsController NSManagedObject 更改保存不工作

获取 NSManagedObject 未保存

NSManagedObject 不插入它:相关的很多

NSManagedObject 保存或插入检查

插入的 NSManagedObject 无法保存时会发生啥情况?