iOS CoreData详解(六)深入理解数据模型
2015-06-05 13:02
591 查看
原创Blog,转载请注明出处
blog.csdn.net/hello_hwc
之前的五篇文章
1. 堆栈与基本概念
2. 基本操作
3. 与Tableview协作-NSFetchedResultController
4. CoreData原理Faulting and Uniquing
5. CoreData与多线程
前言:Coredata是一个良好的对象图管理工具。那么对象图也就是实体(Entity)的理解就尤为重要。实体包括两个部分,属性和实体之间的关系.
这是本文要讲解的数据模型
![](http://img.blog.csdn.net/20150605161455618)
一个员工隶属于一个部门
一个部门有多个员工
![](http://img.blog.csdn.net/20150603132901359)
其中
属性分为很多种
Optional 可选/必须
很好理解,就是可选属性可以不设置,但是必须的属性就必须设置,否则在存储的时候会失败。这里要注意一点,可选属性不要设置默认值,因为会引起混淆。
Transient 瞬态
这个属性是很有用的,它的意义是除了不持久化到本地外,其他的与完全参与到对象图的管理中。这比临时变量好多了,因为支持undo,支持对象图管理
Indexed索引
和数据库的索引类似,索引能够大幅度提高查询速度,但是会增大表的大小,也会降低写入的速度。因为每次写入都要相应的更新索引
Validation 验证
可以进行一些简单的验证,例如图中对于字符串可以验证长度。以及String是否符合一个正则表达式。
更复杂的验证要重写KVC代理的方法(验证的例子来自于文档)
属性层次的验证,重写
例如验证一个Age属性
当然,也支持其他验证,例如插入删除更新的时候验证。
这种验证的顺序首先要验证super,然后验证自己的逻辑,如果二者都有错误,则要把两个错误合并然后返回。例如
如何合并两个NSError,返回一个NSError
含有多个NSError的error code是code:NSValidationMultipleErrorsError
把多个errors添加到一个数组,然后设置NSDetailedErrorsKey,这个key就是可以对应获得的error数组。
![](http://img.blog.csdn.net/20150605161254203)
关系分为三种
one to one 一对一;例如
one to many 一对多
many to many 多对多
关系还有一个属性是Inverse,除了特殊情况,是一定要选的,这个属性表示了对应关系。也是CoreData进行对象图维护的依据。
在Destination中有大量对象的时候有用。
这种情况很少用,因为要自己维护对象图
blog.csdn.net/hello_hwc
之前的五篇文章
1. 堆栈与基本概念
2. 基本操作
3. 与Tableview协作-NSFetchedResultController
4. CoreData原理Faulting and Uniquing
5. CoreData与多线程
前言:Coredata是一个良好的对象图管理工具。那么对象图也就是实体(Entity)的理解就尤为重要。实体包括两个部分,属性和实体之间的关系.
这是本文要讲解的数据模型
一个员工隶属于一个部门
一个部门有多个员工
属性(Attributes)
一个属性的截图其中
属性分为很多种
Optional 可选/必须
很好理解,就是可选属性可以不设置,但是必须的属性就必须设置,否则在存储的时候会失败。这里要注意一点,可选属性不要设置默认值,因为会引起混淆。
Transient 瞬态
这个属性是很有用的,它的意义是除了不持久化到本地外,其他的与完全参与到对象图的管理中。这比临时变量好多了,因为支持undo,支持对象图管理
Indexed索引
和数据库的索引类似,索引能够大幅度提高查询速度,但是会增大表的大小,也会降低写入的速度。因为每次写入都要相应的更新索引
Validation 验证
可以进行一些简单的验证,例如图中对于字符串可以验证长度。以及String是否符合一个正则表达式。
更复杂的验证要重写KVC代理的方法(验证的例子来自于文档)
属性层次的验证,重写
-(BOOL)validate<Key>:(id *)ioValue error:(NSError **)outError
例如验证一个Age属性
-(BOOL)validateAge:(id *)ioValue error:(NSError **)outError { if (*ioValue == nil) { // trap this in setNilValueForKey? new NSNumber with value 0? return YES; } if ([*ioValue floatValue] <= 0.0) { if (outError != NULL) { NSString *errorStr = NSLocalizedStringFromTable( @"Age must greater than zero", @"Employee", @"validation: zero age error"); NSDictionary *userInfoDict = @{ NSLocalizedDescriptionKey : errorStr }; NSError *error = [[NSError alloc] initWithDomain:EMPLOYEE_ERROR_DOMAIN code:PERSON_INVALID_AGE_CODE userInfo:userInfoDict]; *outError = error; } return NO; } else { return YES; }
当然,也支持其他验证,例如插入删除更新的时候验证。
这种验证的顺序首先要验证super,然后验证自己的逻辑,如果二者都有错误,则要把两个错误合并然后返回。例如
- (BOOL)validateForInsert:(NSError **)error { BOOL propertiesValid = [super validateForInsert:error]; // could stop here if invalid BOOL consistencyValid = [self validateConsistency:error]; return (propertiesValid && consistencyValid); } - (BOOL)validateForUpdate:(NSError **)error { BOOL propertiesValid = [super validateForUpdate:error]; // could stop here if invalid BOOL consistencyValid = [self validateConsistency:error]; return (propertiesValid && consistencyValid); } - (BOOL)validateConsistency:(NSError **)error { static NSCalendar *gregorianCalendar; BOOL valid = YES; NSDate *myBirthday = [self birthday]; if ((myBirthday != nil) && ([[self hasDrivingLicense] boolValue] == YES)) { if (gregorianCalendar == nil) { gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; } NSDateComponents *components = [gregorianCalendar components:NSYearCalendarUnit fromDate:myBirthday toDate:[NSDate date] options:0]; int years = [components year]; if (years < 16) { valid = NO; // don't create an error if none was requested if (error != NULL) { NSBundle *myBundle = [NSBundle bundleForClass:[self class]]; NSString *drivingAgeErrorString = [myBundle localizedStringForKey:@"TooYoungToDriveError" value:@"Person is too young to have a driving license." table:@"PersonErrorStrings"]; NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; [userInfo setObject:drivingAgeErrorString forKey:NSLocalizedFailureReasonErrorKey]; [userInfo setObject:self forKey:NSValidationObjectErrorKey]; NSError *drivingAgeError = [NSError errorWithDomain:PERSON_DOMAIN code:NSManagedObjectValidationError userInfo:userInfo]; // if there was no previous error, return the new error if (*error == nil) { *error = drivingAgeError; } // if there was a previous error, combine it with the existing one else { *error = [self errorFromOriginalError:*error error:drivingAgeError]; } } } } return valid;
如何合并两个NSError,返回一个NSError
含有多个NSError的error code是code:NSValidationMultipleErrorsError
把多个errors添加到一个数组,然后设置NSDetailedErrorsKey,这个key就是可以对应获得的error数组。
- (NSError *)errorFromOriginalError:(NSError *)originalError error:(NSError *)secondError { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; NSMutableArray *errors = [NSMutableArray arrayWithObject:secondError]; if ([originalError code] == NSValidationMultipleErrorsError) { [userInfo addEntriesFromDictionary:[originalError userInfo]]; [errors addObjectsFromArray:[userInfo objectForKey:NSDetailedErrorsKey]]; } else { [errors addObject:originalError]; } [userInfo setObject:errors forKey:NSDetailedErrorsKey]; return [NSError errorWithDomain:NSCocoaErrorDomain code:NSValidationMultipleErrorsError userInfo:userInfo]; }
实体之间的关系(Relationship)
关系分为三种
one to one 一对一;例如
one to many 一对多
many to many 多对多
关系还有一个属性是Inverse,除了特殊情况,是一定要选的,这个属性表示了对应关系。也是CoreData进行对象图维护的依据。
关系的删除规则-Delete Rule
Deny
关系的destination中只要有一个对象,就不能删除,例如如果还有一个员工,就不能删除部门Nullify
删除源头后,destination对应的都设为nil(只在逆向关系Optional的时候有效)。例如,删除一个部门,则把部门中的员工对应的部门信息都设为nilCascade
删除源头后,删除destination所有对象。删除部门了以后,删除所有的员工对象。NoAction
删除源头后,对Destination不做任何操作在Destination中有大量对象的时候有用。
这种情况很少用,因为要自己维护对象图
相关文章推荐
- ios 学习资料
- iOS中动态计算字符串的长度
- IOS的企业版安装包 点击链接直接安装的方式 plist方式
- ios旋转问题
- iOS 蓝色文件夹和黄色文件夹的区别
- IOS 保存图片至相册
- iOS第三方支付-银联支付
- ios 计算 文本高度!
- iOS开发-widget基础
- iOS利用Runtime自定义控制器POP手势动画
- iOS开发- 文件共享(利用iTunes导入文件, 并且显示已有文件)
- iOS动画效果整理
- iOS中AutoLayer自动布局流程及相关方法
- iOS image生成图片
- ios远程推送------------->非常详细
- Nagios简介
- [IOS 开发] 利用Runtime自定义控制器POP手势动画
- 解决ios safari中按钮圆角问题
- 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记30 ScrollView Demo实战
- [转]IOS如何访问通讯录