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

简介:
上一篇文章用实际代码演示了Core Data应用中基本的增删改查操作,使用的是NSManagedObject对象,利用 KVC来修改、获取对象的属性值。
除此之外,我们还可以创建与Player、Team相对应的具体的NSManagedObject子类,如下图:



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

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

@end


@implementation Player

@dynamic age;
@dynamic name;

@end
这里的属性age和name并没有使用@synthesize进行合成,而是使用 @dynamic,表明该属性的 访问函数并非由该类来提供。
有了自定义子类后,我们就可以更简洁地操作对象,比如对Team的读写可以改成:
    NSArray *teamArray = [self fetchTeamList];
    if (teamArray) {
        for (Team *teamObject in teamArray) {
            NSLog(@"Team info : %@, %@\n", teamObject.name, teamObject.city);
        }
    }
以及 :
    Team *teamObject = [NSEntityDescription insertNewObjectForEntityForName:@"Team" inManagedObjectContext:self.managedObjectContext];
    teamObject.name = teamName;
    teamObject.city = teamCity;
然后再执行一遍程序。这时候,发现程序输出重复的球队信息,因为我们创建了两次同样的数据。但实际上一个联盟不应该存在相同名称的两支球队,所以我们应该在插入数据的时候进行验证(这种情况下,创建Team的函数也根据含义而改名):
- (BOOL)insertTeamWithName:(NSString *)teamName city:(NSString *)teamCity
{
    if (!teamName || !teamCity) {
        return NO;
    }
    
    Team *teamObject = [self getTeamInfoByName:teamName];
    if (nil == teamObject) {
        teamObject = [NSEntityDescription insertNewObjectForEntityForName:@"Team" inManagedObjectContext:self.managedObjectContext];
    }
    
    teamObject.name = teamName;
    teamObject.city = teamCity;
    
    return YES;
}

- (Team *)getTeamInfoByName:(NSString *)teamName
{
    Team *teamObject = nil;
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    
    NSEntityDescription *teamEntity = [NSEntityDescription entityForName:@"Team" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:teamEntity];
    
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", teamName];
    [fetchRequest setPredicate:predicate];
    [fetchRequest setFetchLimit:1];
    
    NSError *error = NULL;
    NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (error) {
        NSLog(@"Error : %@\n", [error localizedDescription]);
    }
    
    if (array && [array count] > 0) {
        teamObject = [array objectAtIndex:0];
    }
    
    [fetchRequest release], fetchRequest = nil;
    
    return teamObject;
}
把已经安装的App删除,然后重新运行下程序,可以看到不管运行多少次,都只会有Heat和Lakers两支球队的信息输出。

这是我们显式创建新的NSManagedObject实例时所采取的去重方案,使用 NSPredicate进行条件查询,如果已经存在指定名称的球队就不再重复创建。
如果是在关联属性时这么写代码,比如为一支球队添加多名球员,会显得有点冗余。对于这种情况,可以进行 属性验证,这会和 NSPredicate的使用放在后面进一步讨论。

Brief Talk About Core Data Series, Part 3 : Understanding NSManagedObject & NSPredicate

Jason Lee @ Hangzhou

目录
相关文章
|
7月前
|
存储 测试技术
SAP ABAP OData 服务 Data Provider Class 的 GET_ENTITYSET 方法实现指南试读版
SAP ABAP OData 服务 Data Provider Class 的 GET_ENTITYSET 方法实现指南试读版
34 0
|
安全
「最简单」的 Core Data 上手指南
本文讲的是「最简单」的 Core Data 上手指南,在过去的几个月里,我花费了大量的时间在研究 Core Data 之上,我得去处理一个使用了很多陈旧的代码,糟糕的 Core Data 以及违反了多线程安全的项目。讲真,Core Data 学习起来非常的困难
884 0
|
iOS开发
在 Swift Playgrounds 中使用 Core Data 模型
本文讲的是在 Swift Playgrounds 中使用 Core Data 模型,我很好奇你是否能拿到一个由 Xcode 的数据模型设计创建的 .xcdatamodeld 文件,并在某个背景使用这个文件... 简短的答案是不可以。
1208 0