将 NSManagedObjectModel 中的关系添加到以编程方式创建的 NSEntityDescription [英] Adding relationships in NSManagedObjectModel to programmatically created NSEntityDescription

查看:17
本文介绍了将 NSManagedObjectModel 中的关系添加到以编程方式创建的 NSEntityDescription的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当你编写一个使用 CoreData 的静态库时,在项目中包含一个普通的 .xdatamodeld 文件会造成很大的混乱,因为你不能仅仅将它的编译版本 (.momd) 链接到你的二进制文件中,所以最好创建整个 NSManagedObjectModel 代码如下:

When you write a static library which uses CoreData there's a big mess including a normal .xdatamodeld file into the project because you simply cannot just link its compiled version (.momd) into your binary, so it's better to create the whole NSManagedObjectModel in the code like this:

NSAttributeDescription *dateAttribute = NSAttributeDescription.new;

dateAttribute.name = @"timestamp";
dateAttribute.attributeType = NSDoubleAttributeType;
dateAttribute.optional = NO;
dateAttribute.indexed = YES;

NSAttributeDescription *payloadAttribute = NSAttributeDescription.new;

payloadAttribute.name = @"payload";
payloadAttribute.attributeType = NSBinaryDataAttributeType;
payloadAttribute.optional = NO;
payloadAttribute.indexed = NO;

NSEntityDescription *entry = NSEntityDescription.new;

entry.name = entry.managedObjectClassName = NSStringFromClass(MyCustomEntry.class);
entry.properties = @[dateAttribute, payloadAttribute];

NSManagedObjectModel *mom = NSManagedObjectModel.new;

mom.entities = @[entry];

一切都很完美......

And everything is just perfect....

但是!等等,如果我的 NSManagedObjectModel 中有多个实体,并且它们是相关的(对多、反向等),我到底要如何在代码中连接它们,例如示例上面,如果没有那个漂亮的 Xcode 编辑器,您可以通过几次鼠标点击来建立关系?

But! Wait, if I have more than one entity in my NSManagedObjectModel and they are related (to-many, inversed, and so on), how in the world I gonna connect them in the code, like in example above, without that nice Xcode editor, where you make relationships with several mouse clicks?

示例

想象一下,我们有一个类 MyCustomElement,它与上面代码中的 MyCustomEntry 几乎相同.现在,这是它们的界面,如果我使用 Xcode 生成实体,它们将如何显示:

Imagine, we have a class MyCustomElement, which is almost the same as in MyCustomEntry from the code above. Now, here're their interfaces how they would appear if I used Xcode generation for entities:

@interface MyCustomEntry : NSManagedObject

@property (nonatomic, retain) NSNumber *timestamp;
@property (nonatomic, retain) NSData *payload;
@property (nonatomic, retain) MyCustomElement *element;

@end

@interface MyCustomElement : NSManagedObject

@property (nonatomic, retain) NSNumber * timestamp;
@property (nonatomic, retain) NSString * identifier;
@property (nonatomic, retain) NSSet *entries;

@end

@interface MyCustomElement (CoreDataGeneratedAccessors)

- (void)addEntriesObject:(MyCustomEntry *)value;
- (void)removeEntriesObject:(MyCustomEntry *)value;
- (void)addEntries:(NSSet *)values;
- (void)removeEntries:(NSSet *)values;

@end

我需要为他们创建什么 NSRelationshipDescription 以及如何初始化它?

What NSRelationshipDescription I need to create for them and how to init it?

推荐答案

关系由 NSRelationshipDescription 对象描述.以下代码为具有关系的MyCustomEntry"、MyCustomElement"创建两个实体描述

Relationships are described by NSRelationshipDescription objects. The following code creates two entity descriptions for "MyCustomEntry", "MyCustomElement" with relationships

  • entries (MyCustomElement --> MyCustomEntry, to-many),
  • element (MyCustomEntry --> MyCustomElement,一对一),entries 的逆.
  • entries (MyCustomElement --> MyCustomEntry, to-many),
  • element (MyCustomEntry --> MyCustomElement, to-one), inverse of entries.

两个实体都只有一个字符串属性标识符"(为了节省一些代码行).

Both entities have only a string attribute "identifier" (to save some lines of code).

目标-c:

NSEntityDescription *entry = [[NSEntityDescription alloc] init];
[entry setName:@"MyCustomEntry"];
[entry setManagedObjectClassName:@"MyCustomEntry"];

NSAttributeDescription *entryIdAttribute = [[NSAttributeDescription alloc] init];
entryIdAttribute.name = @"identifier";
entryIdAttribute.attributeType = NSStringAttributeType;

NSEntityDescription *element = [[NSEntityDescription alloc] init];
[element setName:@"MyCustomElement"];
[element setManagedObjectClassName:@"MyCustomElement"];

NSAttributeDescription *elementIdAttribute = [[NSAttributeDescription alloc] init];
elementIdAttribute.name = @"identifier";
elementIdAttribute.attributeType = NSStringAttributeType;

// To-many relationship from "Element" to "Entry":
NSRelationshipDescription *entriesRelation = [[NSRelationshipDescription alloc] init];

// To-one relationship from "Entry" to "Element":
NSRelationshipDescription *elementRelation = [[NSRelationshipDescription alloc] init];

[entriesRelation setName:@"entries"];
[entriesRelation setDestinationEntity:entry];
[entriesRelation setMinCount:0];
[entriesRelation setMaxCount:0]; // max = 0 for to-many relationship
[entriesRelation setDeleteRule:NSCascadeDeleteRule];
[entriesRelation setInverseRelationship:elementRelation];

[elementRelation setName:@"element"];
[elementRelation setDestinationEntity:element];
[elementRelation setMinCount:0];
[elementRelation setMaxCount:1]; // max = 1 for to-one relationship
[elementRelation setDeleteRule:NSNullifyDeleteRule];
[elementRelation setInverseRelationship:entriesRelation];

[entry setProperties:@[entryIdAttribute, elementRelation]];
[element setProperties:@[elementIdAttribute, entriesRelation]];

NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] init];
[mom setEntities:@[entry, element]];

Swift(现已针对 Swift 3/4 更新):

Swift (now updated for Swift 3/4):

let entry = NSEntityDescription ()
entry.name = "MyCustomEntry"
entry.managedObjectClassName = "MyCustomEntry"

let entryIdAttribute = NSAttributeDescription()
entryIdAttribute.name = "identifier";
entryIdAttribute.attributeType = .stringAttributeType;

let element = NSEntityDescription()
element.name = "MyCustomElement"
element.managedObjectClassName = "MyCustomElement"

let elementIdAttribute =  NSAttributeDescription()
elementIdAttribute.name = "identifier"
elementIdAttribute.attributeType = .stringAttributeType

// To-many relationship from "Element" to "Entry":
let entriesRelation = NSRelationshipDescription()

// To-one relationship from "Entry" to "Element":
let elementRelation = NSRelationshipDescription ()

entriesRelation.name = "entries"
entriesRelation.destinationEntity = entry
entriesRelation.minCount = 0
entriesRelation.maxCount = 0  // max = 0 for to-many relationship
entriesRelation.deleteRule = .cascadeDeleteRule
entriesRelation.inverseRelationship = elementRelation

elementRelation.name = "element"
elementRelation.destinationEntity = element
elementRelation.minCount = 0
elementRelation.maxCount = 1 // max = 1 for to-one relationship
elementRelation.deleteRule = .nullifyDeleteRule
elementRelation.inverseRelationship = entriesRelation

entry.properties = [entryIdAttribute, elementRelation]
element.properties = [elementIdAttribute, entriesRelation]

let mom = NSManagedObjectModel()
mom.entities = [entry, element]

我已经测试了这段代码,它似乎可以工作,所以我希望它对你有用.

I have tested this code and it seems to work, so I hope that it will be useful to you.

这篇关于将 NSManagedObjectModel 中的关系添加到以编程方式创建的 NSEntityDescription的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆