`
dcj3sjt126com
  • 浏览: 1826682 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

    博客分类:
  • IOS
阅读更多
上一篇文章用实际代码演示了Core Data应用中基本的增删改查操作,使用的是NSManagedObject对象,利用KVC来修改、获取对象的属性值。
除此之外,我们还可以创建与Player、Team相对应的具体的NSManagedObject子类,如下图:
 
 
Xcode会为我们生成子类的代码,如Player的接口声明和实现(汗,从Xcode复制代码到Evernote,有些空格会被省略):
  1. @interface Player : NSManagedObject  
  2.   
  3. @property (nonatomic, retain) NSNumber * age;  
  4. @property (nonatomic, retain) NSString * name;  
  5.   
  6. @end  
  7.   
  8.   
  9. @implementation Player  
  10.   
  11. @dynamic age;  
  12. @dynamic name;  
  13.   
  14. @end  
这里的属性age和name并没有使用@synthesize进行合成,而是使用@dynamic,表明该属性的访问函数并非由该类来提供。
有了自定义子类后,我们就可以更简洁地操作对象,比如对Team的读写可以改成:
  1. NSArray *teamArray = [self fetchTeamList];  
  2. if (teamArray) {  
  3.     for (Team *teamObject in teamArray) {  
  4.         NSLog(@"Team info : %@, %@\n", teamObject.name, teamObject.city);  
  5.     }  
  6. }  
以及 :
  1. Team *teamObject = [NSEntityDescription insertNewObjectForEntityForName:@"Team" inManagedObjectContext:self.managedObjectContext];  
  2. teamObject.name = teamName;  
  3. teamObject.city = teamCity;  
然后再执行一遍程序。这时候,发现程序输出重复的球队信息,因为我们创建了两次同样的数据。但实际上一个联盟不应该存在相同名称的两支球队,所以我们应该在插入数据的时候进行验证(这种情况下,创建Team的函数也根据含义而改名):
  1. - (BOOL)insertTeamWithName:(NSString *)teamName city:(NSString *)teamCity  
  2. {  
  3.     if (!teamName || !teamCity) {  
  4.         return NO;  
  5.     }  
  6.       
  7.     Team *teamObject = [self getTeamInfoByName:teamName];  
  8.     if (nil == teamObject) {  
  9.         teamObject = [NSEntityDescription insertNewObjectForEntityForName:@"Team" inManagedObjectContext:self.managedObjectContext];  
  10.     }  
  11.       
  12.     teamObject.name = teamName;  
  13.     teamObject.city = teamCity;  
  14.       
  15.     return YES;  
  16. }  
  17.   
  18. - (Team *)getTeamInfoByName:(NSString *)teamName  
  19. {  
  20.     Team *teamObject = nil;  
  21.       
  22.     NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];  
  23.       
  24.     NSEntityDescription *teamEntity = [NSEntityDescription entityForName:@"Team" inManagedObjectContext:self.managedObjectContext];  
  25.     [fetchRequest setEntity:teamEntity];  
  26.       
  27.     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", teamName];  
  28.     [fetchRequest setPredicate:predicate];  
  29.     [fetchRequest setFetchLimit:1];  
  30.       
  31.     NSError *error = NULL;  
  32.     NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];  
  33.     if (error) {  
  34.         NSLog(@"Error : %@\n", [error localizedDescription]);  
  35.     }  
  36.       
  37.     if (array && [array count] > 0) {  
  38.         teamObject = [array objectAtIndex:0];  
  39.     }  
  40.       
  41.     [fetchRequest release], fetchRequest = nil;  
  42.       
  43.     return teamObject;  
  44. }  
把已经安装的App删除,然后重新运行下程序,可以看到不管运行多少次,都只会有Heat和Lakers两支球队的信息输出。
 
这是我们显式创建新的NSManagedObject实例时所采取的去重方案,使用NSPredicate进行条件查询,如果已经存在指定名称的球队就不再重复创建。
如果是在关联属性时这么写代码,比如为一支球队添加多名球员,会显得有点冗余。对于这种情况,可以进行属性验证,这会和NSPredicate的使用放在后面进一步讨论。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics