gpt4 book ai didi

iphone - 基于属性评估创建CoreData实体

转载 作者:行者123 更新时间:2023-12-03 19:41:57 25 4
gpt4 key购买 nike

假设我有一个实体 MeetingNote,它具有标准属性以及与另一个实体 Tag一对多关系。

MeetingNote 实例中,我想创建另一个名为 Task 的实体的实例,但仅限于 meetingNote.tag.name == 'task'TRUE

您认为对 TaskMeetingNote 之间的关系进行建模的正确方法是什么?或者是否应该存在某种关系,而我应该使用带有适当谓词的获取属性?

最佳答案

首先,核心数据的真正目的不是持久性,而是创建模型- View - Controller 设计应用程序的模型层。这意味着 Core Data 实际上首先是模型/模拟 API,其次是持久性 API。因此,核心数据数据模型应该准确地表示现实世界对象、条件或事件的属性以及它们之间的关系。

因此,当您开始构建数据模型时,您应该忘记 UI、数据源或任何其他实现细节,而只是尝试创建一个反射(reflect)应用程序真实世界对象、条件或事件的模型处理。

其次,虽然数据模型处理实体如何相关,但它并不处理为什么相关的逻辑 实体是相关的。该逻辑通常属于实体的自定义 NSManagedObject 子类中的代码中。在本例中,实体关系的方式MeetingNote 实体与 Task标签原因是,只有当MeetingNote 对象与名称为 taskTag 对象有关系。

因此,您的基本数据模型应如下所示:

MeetingNote{
title:string
date:date
tags<<-->>Tag.meetingNotes
tasks<-->>Task.meetingNote
}

Task{
name:string
meetingNote<<-->MeetingNote.tasks
}

Tag{
name:string
meetingNotes<<-->>MeetingNote.tags
}

现在的问题是在哪里坚持为什么的自定义逻辑。逻辑上最简单的方法是为 MeetingNote.tags 属性创建一个自定义访问器,用于检查添加或删除到 MeetingNote 实例 的标签名称是否等于 task,如果是,则从实例的 MeetingNote.tasks 关系中添加或删除 Task 对象。

但是,这会明显降低性能,因为必须检查添加或删除的每个标签。更好的解决方案是将自定义添加到仅一个点,仅当 MeetingNote.tags.name' 的确切条件包含 task` 值时才调用该点。

假设您有以下限制:

  1. MeetingNote 对象不能拥有相关的 Task 对象,除非同时具有 name==“task” 的 Tag 对象。

  2. 如果 MeetingNote 对象确实有一个名为 ==“task”的 Tag 对象,则它必须至少有一个相关的 Task 对象。

  3. 如果 MeetingNote 对象失去与 name=="task"Tag 对象的关系,则它会丢失所有任务。



此时很明显,`name=="task"的标签对象是一个特殊的对象,其行为与其他标签不同。这证明并要求它有自己的实体和子类,因此我们将添加到数据模型中:



TaskTag:Tag{
}

由于 TaskTag 实体继承自 Tag 实体,因此它可以自动继承 Tag.meetingNotes 关系中的 ,因此它将表现为从任何 MeetinNote 对象的角度来看 Tag 对象。

然后在 TaskTag NSManagedObject 子类中我们添加以下代码:

-(NSString *) name {
// the name of a TaskTag is always "task"
// you should set the defalut value in the data model to "task" as well.
return @"task";
}

-(void) setName:(NSString *)name{
return; // the name can never be changed
}

- (void)addMeetingNotesObject:(MeetingNote *)value {
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"meetingNotes" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"meetingNotes"] addObject:value];

// If the meeting object does not an existing task, add one
if ([value.tasks count]==0 ) {
Task *t=[NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:self.managedObjectContext];
t.meetingNote=value;
}

[self didChangeValueForKey:@"meetingNotes" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[changedObjects release];
}

- (void)removeMeetingNotesObject:(MeetingNote *)value {
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"meetingNotes" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"meetingNotes"] removeObject:value];

// A MeetingNote object cannot have any task without a taskTag so remove all task objects
if ([value.tasks count]!=0 ) {
[value removeTasks:value.tasks]; // removes all tasks from meeting notes
}

[self didChangeValueForKey:@"meetingNotes" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[changedObjects release];
}

- (void)addMeetingNotes:(NSSet *)value {
[self willChangeValueForKey:@"meetingNotes" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value];
[[self primitiveValueForKey:@"meetingNotes"] unionSet:value];

Task *newTask;
// same as addMeetingNotesObject:
for (MeetingNote *meetNote in value) {
if ([meetNote.tasks count]==0 ) {
newTask=[NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:self.managedObjectContext];
newTask.meetingNote=value;
}
}

[self didChangeValueForKey:@"meetingNotes" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value];
}

- (void)removeMeetingNotes:(NSSet *)value {
[self willChangeValueForKey:@"meetingNotes" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value];
[[self primitiveValueForKey:@"meetingNotes"] minusSet:value];

//removeMeetingNotesObject:
for (MeetingNote *meetNote in value) {
[meetNote removeTasks:meetNote.tasks];
}
[self didChangeValueForKey:@"meetingNotes" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value];
}
// Note: This code is not compiled and my contain errors.

此代码将自动强制执行上述约束,而无需执行任何其他操作。您还可以自定义 Task 子类,以根据与其相关的 MeetingNote 对象的某些属性自动设置其名称。

现在您已在数据模型中掌握了所有原因逻辑,并且您的约束将自动执行。这可能不是您需要的确切解决方案,但您已经明白了。

关于iphone - 基于属性评估创建CoreData实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6489364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com