行走核心数据图表到多个关系似乎总是很尴尬,有更好的方法吗?

时间:2011-07-20 12:54:10

标签: cocoa core-data

我能够使Core Data能够很好地工作并达到我想要的效果,但是当我走到很多关系时我总觉得很尴尬,因为对于我的典型目的,NSSet是相当无用的。

一个例子是,如果我获得了具有属性“nameOfZoo”的实体“Zoo”的NSManagedObject和多对多关系“animalCages”,则指向具有属性“nameOfSpecies”的Entity“AnimalCage”的to-many关系并且 - 指向实体“IndividualAnimal”的多少关系

Zoo [nameOfZoo] - >> AnimalCage [nameOfSpecies] - >>动物

因此,获得顶级Zoo对象,这很简单。但后来我想得到nameOfSpecies“Canus Lupus”的数据。我想写的代码是:


// Normal NSEntityRequest or whichever it is, I have no gripe with this
NSManagedObject *zoo = ..the request to get the one Zoo..;

// I want to get the object where the key "nameOfSpecies" is set to "CanusLupus" NSManagedObject *wolf = [[zoo animalCages] object:@"Canus Lupus" forKey:@"nameOfSpecies"];

显然,我不能以这种方式获得狼。相反,我必须编写10行代码(感觉像100行代码)来首先获取集合,然后设置搜索谓词请求,并声明一个错误变量,执行请求,然后获取结果数组,然后得到该数组的第一个元素..如果我想在树下走得更远,找到名为“Wolfy”的动物,那么我必须重新做一遍。

我正确地做事还是愚蠢地更容易?我想我可以在NSSet上放一个类别,也许我会,但我觉得应该有更好的内置方式。如果没有,为什么?

1 个答案:

答案 0 :(得分:1)

如果你有这样的数据模型:

Zoo{
  name:string
  animalCages<-->>AnimalCage.zoo
}

AnimalCage{
  nameOfSpecies:string
  zoo<<-->Zoo.animalCages
  animals<-->>Animal.animalCage
}

Animal{
  name:string
  animalCage<<-->AnimalCage.animals
}

根据给定AnimalCage对象的物种名称查找特定Zoo

  NSString *soughtSpecies=@"Canis Lupis"; // normally this variable would be passed in to the method
  NSPredicate *p=[NSPredicate predicateWithFormat:@"nameOfSpecies==%@", soughtSpecies];
  NSSet *wolves=[[zoo animalCages] filteredSetUsingPredicate:p];

如果你喜欢积木,也可以使用objectPassingTest:

如果您使用自定义NSManagedObject子类,那么您将获得自定义访问器方法并可以使用self.dot表示法,因此上面将是:

  Zoo *zoo= // fetch the appropriate zoo object
  NSString *soughtSpecies=@"Canis Lupis";
  NSPredicate *p=[NSPredicate predicateWithFormat:@"nameOfSpecies==%@", soughtSpecies];
  NSSet *wolves=[zoo.animalCages filteredSetUsingPredicate:p];

如果你事先知道你必须经常发现笼子,你可以在Zoo课程的方法中包括上面的内容,例如

@implementation Zoo
//... other stuff
-(AnimalCage *) cageForSpecieNamed:(NSString *) specieName{
  NSPredicate *p=[NSPredicate predicateWithFormat:@"nameOfSpecies==%@", specieName];
  NSSet *wolves=[self.animalCages filteredSetUsingPredicate:p];
  return [wolves anyObject]; // assuming one cage per species
}

Objective-c故意冗长,因为它应该是“自我记录”,并且在开始时为该语言编写的编辑器具有自动完成功能。所以,如果你习惯了一种更具表现力的语言,你可能会做很多工作,但从逻辑上讲,你不是。