iOS开发之Core Data Demo (一)
来源:互联网 发布:源码安装rrdtool 编辑:程序博客网 时间:2024/05/16 07:18
相信大家对iOS开发之Core Data Demo一定不会陌生,但是对于在程序当中如何操纵Core Data Demo,如何能更有效的更新数据,这是学习ios培训每一个人都会遇到的问题,
这节课的主要内容是Core Data的线程安全、Core DataTable View,以及大Demo。
Core Data Thread Safety
NSManagedObjectContext不是线程安全的,只能在创建NSManagedObjectContext的那个线程里访问它。一个数据库有多个UIManagedDocument和context,它们可以在不同的线程里创建,只要能管理好它们之间的关系就没问题。
线程安全的意思是,程序可能会崩溃,如果多路访问同一个NSManagedObjectContext,或在非创建实例的线程里访问实例,app就会崩溃。对此要怎么做呢?NSManagedObjectContext有个方法叫performBlock可以解决这个问题:
[context performBlock:^{ //or performBlockAndWait:
// do stuff with context
}];
它会自动确保block里的东西都在正确的context线程里执行,但这不一定就意味着使用了多线程。事实上,如果在主线程下创建的context,那么这个block会回到主线程来,而不是在其他线程里运行,这个performBlock只是确保block运行在正确的线程里。
NSManagedObjectContext,包括所有使用SQL的Core Data,都有一个parentContext,这就像是另一个NSManagedObjectContext,在真正写入数据库之前要写入到这里。可以获取到parentContext,可以让parentContext调用performBlock来做一些事,这总是在另一个线程里进行。parentContext和创建的NSManagedObjectContext不在一个线程里运行,可以通过performBlock在那个线程里执行你要做的事。记住,如果改变了parentContext,必须保存,然后重新获取child context。如果你想在非主线程载入很多内容,那么就全部放入数据库,然后在主线程去获取,这个效率非常快。
Core Data and Table View
ios里有一个非常重要的类NSFetchedResultsController,它不是一个viewController,而是控制fetchedResults与tableView通信方式的controller,所以这个NSFetchedResultsController是一个NSObject。
它的作用就是用来连接NSFetchedResultsController和UITableViewController的,而且连接的方法很强大。首先,它可以回答所有UITableView DataSource、protocol的问题,唯一不能回答的是cellForRowAtIndexPath。这是个NSFetchedResultsController的例子:
- (NSUInteger)numberOfSectionsInTableView:(UITableView *)sender{
return [[self.fetchedResultsController sections] count];
}
- (NSUInteger)tableView:(UITableView *)sender numberOfRowsInSection:(NSUInteger)section{
return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}
tableView有个property是NSFetchedResultsController,就是这个self.fetchedResultsController。
cellForRowAtIndexPath也是很容易实现的,因为NSFetchedResultsController有objectAtIndexPath这个方法,你给出一个index,它会返回给你该row所显示的NSManagedObject:
- (NSManagedObject *)objectAtIndexPath:(NSIndexPath *)indexPath;
如果要实现cellForRowAtIndexPath,可以像下面这样做:
- (UITableViewCell *)tableView:(UITableView *)sender
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = ...;
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
// load up the cell based on the properties of the managedObject
// of course, if you had a custom subclass, you’d be using dot notation to get them
return cell;
}
有了managedObject,可以用valueForKey或者子类它,用.号来获取它的property。在一个Core Data驱动的tableView里,每一行都是通过数据库里的对象来表示的,一对一的关系。
如何创建这个NSFetchedResultsController呢?这是个如何alloc/init的例子:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@“Photo”];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@“title” ...];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
request.predicate = [NSPredicate predicateWithFormat:@“whoTook.name = %@”, photogName];
NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:(NSFetchRequest *)request managedObjectContext:(NSManagedObjectContext *)context
sectionNameKeyPath:(NSString *)keyThatSaysWhichSectionEachManagedObjectIsIn cacheName:@“MyPhotoCache”; // careful!
如果用这个fetch request来创建NSFetchedResultsController,那么table的每一行的照片的photographer名字都会对应这个字符串。cacheName就是缓存名,缓存速度很快,但有一点要小心:如果改变了fetch request的参数,比如改了predicate或者sortDescriptors,缓存会被破坏。如果真的要通过NSFetchedResultsController改fetch request,那么得删除缓存。NSFetchedResultsController里有个工厂方法可以删除缓存,或者可以就设为null,这样就不会有缓存,对于小型数据库,可以不用缓存。对于一个非常大型的数据库,如果要改request,得先删除缓存。另一个参数sectionNameKeyPath表示每个managedObject所在的section,这就是objects的一个attribute,这个例子里就是photo的一个attribute,如果问这个attribute关于photo的事,它会告诉我这个section的title,所以这里就是section的title。
如果context改变了,NSFetchedResultsController会自动更新table,只要把两个东西连接起来就行。唯一的前提是,这些改变都要发生在创建NSFetchedResultsController的那个context里。原理是,NSFetchedResultsController有个delegate,它会发很多消息,例如,添加了对象或者对象的一个属性改了等等,然后tableView就会去做相应的调整,事实上还是要在tableView里写些代码的。
这节课的主要内容是Core Data的线程安全、Core DataTable View,以及大Demo。
Core Data Thread Safety
NSManagedObjectContext不是线程安全的,只能在创建NSManagedObjectContext的那个线程里访问它。一个数据库有多个UIManagedDocument和context,它们可以在不同的线程里创建,只要能管理好它们之间的关系就没问题。
线程安全的意思是,程序可能会崩溃,如果多路访问同一个NSManagedObjectContext,或在非创建实例的线程里访问实例,app就会崩溃。对此要怎么做呢?NSManagedObjectContext有个方法叫performBlock可以解决这个问题:
[context performBlock:^{ //or performBlockAndWait:
// do stuff with context
}];
它会自动确保block里的东西都在正确的context线程里执行,但这不一定就意味着使用了多线程。事实上,如果在主线程下创建的context,那么这个block会回到主线程来,而不是在其他线程里运行,这个performBlock只是确保block运行在正确的线程里。
NSManagedObjectContext,包括所有使用SQL的Core Data,都有一个parentContext,这就像是另一个NSManagedObjectContext,在真正写入数据库之前要写入到这里。可以获取到parentContext,可以让parentContext调用performBlock来做一些事,这总是在另一个线程里进行。parentContext和创建的NSManagedObjectContext不在一个线程里运行,可以通过performBlock在那个线程里执行你要做的事。记住,如果改变了parentContext,必须保存,然后重新获取child context。如果你想在非主线程载入很多内容,那么就全部放入数据库,然后在主线程去获取,这个效率非常快。
Core Data and Table View
ios里有一个非常重要的类NSFetchedResultsController,它不是一个viewController,而是控制fetchedResults与tableView通信方式的controller,所以这个NSFetchedResultsController是一个NSObject。
它的作用就是用来连接NSFetchedResultsController和UITableViewController的,而且连接的方法很强大。首先,它可以回答所有UITableView DataSource、protocol的问题,唯一不能回答的是cellForRowAtIndexPath。这是个NSFetchedResultsController的例子:
- (NSUInteger)numberOfSectionsInTableView:(UITableView *)sender{
return [[self.fetchedResultsController sections] count];
}
- (NSUInteger)tableView:(UITableView *)sender numberOfRowsInSection:(NSUInteger)section{
return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}
tableView有个property是NSFetchedResultsController,就是这个self.fetchedResultsController。
cellForRowAtIndexPath也是很容易实现的,因为NSFetchedResultsController有objectAtIndexPath这个方法,你给出一个index,它会返回给你该row所显示的NSManagedObject:
- (NSManagedObject *)objectAtIndexPath:(NSIndexPath *)indexPath;
如果要实现cellForRowAtIndexPath,可以像下面这样做:
- (UITableViewCell *)tableView:(UITableView *)sender
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = ...;
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
// load up the cell based on the properties of the managedObject
// of course, if you had a custom subclass, you’d be using dot notation to get them
return cell;
}
有了managedObject,可以用valueForKey或者子类它,用.号来获取它的property。在一个Core Data驱动的tableView里,每一行都是通过数据库里的对象来表示的,一对一的关系。
如何创建这个NSFetchedResultsController呢?这是个如何alloc/init的例子:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@“Photo”];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@“title” ...];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
request.predicate = [NSPredicate predicateWithFormat:@“whoTook.name = %@”, photogName];
NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:(NSFetchRequest *)request managedObjectContext:(NSManagedObjectContext *)context
sectionNameKeyPath:(NSString *)keyThatSaysWhichSectionEachManagedObjectIsIn cacheName:@“MyPhotoCache”; // careful!
如果用这个fetch request来创建NSFetchedResultsController,那么table的每一行的照片的photographer名字都会对应这个字符串。cacheName就是缓存名,缓存速度很快,但有一点要小心:如果改变了fetch request的参数,比如改了predicate或者sortDescriptors,缓存会被破坏。如果真的要通过NSFetchedResultsController改fetch request,那么得删除缓存。NSFetchedResultsController里有个工厂方法可以删除缓存,或者可以就设为null,这样就不会有缓存,对于小型数据库,可以不用缓存。对于一个非常大型的数据库,如果要改request,得先删除缓存。另一个参数sectionNameKeyPath表示每个managedObject所在的section,这就是objects的一个attribute,这个例子里就是photo的一个attribute,如果问这个attribute关于photo的事,它会告诉我这个section的title,所以这里就是section的title。
如果context改变了,NSFetchedResultsController会自动更新table,只要把两个东西连接起来就行。唯一的前提是,这些改变都要发生在创建NSFetchedResultsController的那个context里。原理是,NSFetchedResultsController有个delegate,它会发很多消息,例如,添加了对象或者对象的一个属性改了等等,然后tableView就会去做相应的调整,事实上还是要在tableView里写些代码的。
- iOS开发之Core Data Demo (一)
- iOS开发-数据储存Core Data(一)
- iOS 之Core Data操作(一)
- ios编程之Core Data(一)
- iOS应用开发视频教程笔记(十四)Core Data Demo
- IOS开发(96)之Core Data
- iOS开发之Core Data数据存储
- iOS开发中,Core Data的使用笔记(一)
- [iOS]Core Data浅析(一)
- IOS数据持久化之Core Data(一) - 框架说明
- [ios开发基础之 Core Data [1] ]Core Data数据持久性存储基础教程
- IOS开发之——Core Data学习
- IOS开发之——Core Data学习
- IOS开发之——Core Data学习
- ios开发学习笔记--数据持久化之Core Data
- iOS大典之Core Data
- iOS Swift教程 Core Data (一)Hello Core Data
- Core Data demo介绍
- struts上传文件
- Android学习笔记
- 企业实施精准营销易出现的问题及其解决方案
- 常用的MySQL数据库命令大全
- ICCV 2013的人脸特征点检评测及代码
- iOS开发之Core Data Demo (一)
- 新建maven子模块 出现 Unable to read parent POM
- 20130828C语言编程实践课第八天
- 使用T-sql递归语句注意的地方
- C#异步编程
- 性能测试结果
- hdu 4090 GemAnd Prince (bfs+dfs+模拟)
- android 中的 startActivityForResult
- Hoj 2468 GSM