使用 MagicalRecord 在核心数据中映射和发布实体

Posted

技术标签:

【中文标题】使用 MagicalRecord 在核心数据中映射和发布实体【英文标题】:Mapping ADN Post Entities in Core Data using MagicalRecord 【发布时间】:2012-12-15 13:25:25 【问题描述】:

我在将帖子从 ADN 映射到我的数据库时遇到问题。

请记住,我正在使用 MagicalRecord 将 JSON 自动映射到我设置的 NSManagedObjects。

可以在此处查看 JSON:http://web.archive.org/web/20170123035402/https://developers.app.net/reference/resources/post/,特别是包含实体的部分。

我的核心数据模型已经设置了以下关系:

Post <-> Entities <->> Links/Hashtags/Mentions

已经使用正确的名称设置了关系,因此 MagicalRecord 应该能够很好地映射树。 Post 对象有一堆属性。它与实体对象的关系称为“实体”,这似乎是由于主键而失败的地方(AFAIK 从它在 MagicalRecord 中的代码中中断)。

由于实体基本上只是一个保存与每个实体类型的关系的对象,因此我没有实体对象的任何属性。不幸的是,它似乎无助于为实体对象设置具有随机名称的属性。

根据以上信息,您有什么不同的做法来正确映射关系和对象吗?是否可以使用我仅用于与每个实体类型的关系的这个空 Entities 对象,有点像 ADN 帖子是如何使用“实体”字典设置的。

【问题讨论】:

【参考方案1】:

首先,你忽略了描述你的“问题”,只描述了你的场景。究竟是什么行为不符合您的预期?

Core Data 实体上是否存在属性不会影响其行为。

然而,“实体”这个名字让我感觉有点刺痛。虽然 NSManagedObject 没有(公共)“实体”属性或方法,但它确实有一个“实体”方法。

更新:我使用以下模型手动创建了一个新的 Core Data 测试项目:

项目 实体 > Foo

还有这段代码:

NSManagedObjectContext *moc = [self managedObjectContext];
NSManagedObject *item = [NSEntityDescription insertNewObjectForEntityForName:@"Item"
                                                      inManagedObjectContext:moc];
NSManagedObject *ent = [NSEntityDescription insertNewObjectForEntityForName:@"Entities"
                                                     inManagedObjectContext:moc];
NSManagedObject *foo = [NSEntityDescription insertNewObjectForEntityForName:@"Foo"
                                                     inManagedObjectContext:moc];

[item setValue:ent forKey:@"entities"];
[foo setValue:ent forKey:@"entities"];

NSLog(@"%@ -> %@ -> %@", item, ent, foo);

效果很好。

更新:我能找到的最接近导致奇怪行为的事情是:

[item setValue:@(YES) forKey:@"deleted"];
[item setValue:@(YES) forKey:@"is_deleted"];

NSLog(@"deleted=%@", [[item valueForKey:@"deleted"] boolValue] ? @"YES" : @"NO");
NSLog(@"is_deleted=%@", [[item valueForKey:@"is_deleted"] boolValue] ? @"YES" : @"NO");

日志会打印“deleted=NO”和“is_deleted=YES”,前一种情况是错误的。预先存在的“isDeleted”方法可防止为“deleted”属性自动生成“deleted”访问器。

【讨论】:

【参考方案2】:

所以问题确实在于 MagicalRecord 和我自己设置 NSManagedObjects 和关系的方式。

MagicalRecord 使用主键来处理关系。如果尚未设置,则使用其中一个属性。在我的例子中,Entities NSManagedObject 没有任何属性,因为我只是使用它来处理与每个实体类型的关系。

这个代码可以在NSObject+MagicalDataImport.m找到:

- (NSString *) MR_lookupKeyForRelationship:(NSRelationshipDescription *)relationshipInfo

    NSEntityDescription *destinationEntity = [relationshipInfo destinationEntity];
    if (destinationEntity == nil) 
    
        MRLog(@"Unable to find entity for type '%@'", [self valueForKey:kMagicalRecordImportRelationshipTypeKey]);
        return nil;
    

    NSString *primaryKeyName = [relationshipInfo MR_primaryKey];

    NSAttributeDescription *primaryKeyAttribute = [[destinationEntity attributesByName] valueForKey:primaryKeyName];
    NSString *lookupKey = [[primaryKeyAttribute userInfo] valueForKey:kMagicalRecordImportAttributeKeyMapKey] ?: [primaryKeyAttribute name];

    return lookupKey;

特别是 [[destinationEntity attributesByName] valueForKey:primaryKeyName]; 返回 nil。

起初我使用名为“test”的属性进行了测试,但我不确定我做了什么没有奏效,也许是清除缓存做得不够好。我再次尝试清除这些关系,所以我不必担心这些关系,然后我在实体NSManagedObject 上添加了一个属性“实体”,一切都很好!

对不起。只需添加答案和 cmets,以防万一有人在使用 MagicalRecord 并且 NSManagedObject 没有任何属性时遇到此问题。

【讨论】:

以上是关于使用 MagicalRecord 在核心数据中映射和发布实体的主要内容,如果未能解决你的问题,请参考以下文章

无法在具有 MagicalRecord [核心数据] 的实体中分配给 ...

MagicalRecord 重新启动应用程序时删除核心数据存储

使用 MagicalRecord 进行核心数据加密

RestKit 两个连续的 enqueueBatchOfObjectRequestOperations 没有直接映射到核心数据

如何在 MagicalRecord saveWith Block 之外创建核心数据实体

MagicalRecord:删除整个数据并再次设置核心数据堆栈