0
点赞
收藏
分享

微信扫一扫

Core Data浅谈系列之三 : 了解NSManagedObject和NSPredicate


​​上一篇文章​​​用实际代码演示了Core Data应用中基本的增删改查操作,使用的是NSManagedObject对象,利用 ​​​KVC​​来修改、获取对象的属性值。



除此之外,我们还可以创建与Player、Team相对应的具体的NSManagedObject子类,如下图:



 




Core Data浅谈系列之三 : 了解NSManagedObject和NSPredicate_xcode


 


Xcode会为我们生成子类的代码,如Player的接口声明和实现(汗,从Xcode复制代码到Evernote,有些空格会被省略):


[cpp]  ​​view plain​​​ ​​copy​​


  1. @interface Player : NSManagedObject

  2. @property (nonatomic, retain) NSNumber * age;
  3. @property (nonatomic, retain) NSString * name;

  4. @end


  5. @implementation Player

  6. @dynamic age;
  7. @dynamic name;

  8. @end


这里的属性age和name并没有使用@synthesize进行合成,而是使用 ​​@dynamic​​​,表明该属性的 ​​访问函数​​并非由该类来提供。


有了自定义子类后,我们就可以更简洁地操作对象,比如对Team的读写可以改成:


[cpp]  ​​view plain​​​ ​​copy​​


  1. NSArray *teamArray = [self fetchTeamList];
  2. if (teamArray) {
  3. for (Team *teamObject in teamArray) {
  4. "Team info : %@, %@\n", teamObject.name, teamObject.city);
  5. }
  6. }


以及 :


[cpp]  ​​view plain​​​ ​​copy​​


  1. Team *teamObject = [NSEntityDescription insertNewObjectForEntityForName:@"Team" inManagedObjectContext:self.managedObjectContext];
  2. teamObject.name = teamName;
  3. teamObject.city = teamCity;


然后再执行一遍程序。这时候,发现程序输出重复的球队信息,因为我们创建了两次同样的数据。但实际上一个联盟不应该存在相同名称的两支球队,所以我们应该在插入数据的时候进行验证(这种情况下,创建Team的函数也根据含义而改名):


[cpp]  ​​view plain​​​ ​​copy​​


  1. - (BOOL)insertTeamWithName:(NSString *)teamName city:(NSString *)teamCity
  2. {
  3. if (!teamName || !teamCity) {
  4. return NO;
  5. }

  6. Team *teamObject = [self getTeamInfoByName:teamName];
  7. if (nil == teamObject) {
  8. "Team" inManagedObjectContext:self.managedObjectContext];
  9. }

  10. teamObject.name = teamName;
  11. teamObject.city = teamCity;

  12. return YES;
  13. }

  14. - (Team *)getTeamInfoByName:(NSString *)teamName
  15. {
  16. Team *teamObject = nil;

  17. NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

  18. "Team" inManagedObjectContext:self.managedObjectContext];
  19. [fetchRequest setEntity:teamEntity];

  20. "name == %@", teamName];
  21. [fetchRequest setPredicate:predicate];
  22. [fetchRequest setFetchLimit:1];

  23. NSError *error = NULL;
  24. NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
  25. if (error) {
  26. "Error : %@\n", [error localizedDescription]);
  27. }

  28. if (array && [array count] > 0) {
  29. teamObject = [array objectAtIndex:0];
  30. }

  31. [fetchRequest release], fetchRequest = nil;

  32. return teamObject;
  33. }


把已经安装的App删除,然后重新运行下程序,可以看到不管运行多少次,都只会有Heat和Lakers两支球队的信息输出。


 


这是我们显式创建新的NSManagedObject实例时所采取的去重方案,使用 ​​NSPredicate​​进行条件查询,如果已经存在指定名称的球队就不再重复创建。


如果是在关联属性时这么写代码,比如为一支球队添加多名球员,会显得有点冗余。对于这种情况,可以进行 ​​属性验证​​​,这会和 ​​NSPredicate的使用​​放在后面进一步讨论。

举报

相关推荐

SwiftUI 和 Core Data

0 条评论