1 #import "AppDelegate.h"
#import "Book.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
-(void)addBookWithTitle:(NSString *)title andAuthor:(NSString *)author andPrice:(NSNumber *)price
{
Book *book = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Book class]) inManagedObjectContext:self.managedObjectContext];
book.title = title;
book.author = author;
book.price = price;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//如果不想每次执行时测试数据都重新插入一遍,可以使用偏好设置,如果已经存在了,就不再进行插入了。
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
BOOL isInserted = [userDefaults boolForKey:@"inInserted"];
if (!isInserted)
{
//插入数据
[self addBookWithTitle:@"*文*" andAuthor:@"徐" andPrice:@10000.1];
[self addBookWithTitle:@"西游记" andAuthor:@"吴承恩" andPrice:@20.5];
[self addBookWithTitle:@"水浒传" andAuthor:@"施耐庵" andPrice:@5.1];
[self addBookWithTitle:@"三国演义" andAuthor:@"罗贯中" andPrice:@10.2];
[self addBookWithTitle:@"史记" andAuthor:@"司马迁" andPrice:@45.3];
[self addBookWithTitle:@"资治通鉴" andAuthor:@"司马光" andPrice:@56.5];
[self saveContext];
//保存偏好设置
[userDefaults setBool:YES forKey:@"inInserted"];
//自动步更新
[userDefaults synchronize];
}
return YES;
}
 #import "BookTableViewController.h"
#import "Book.h"
#import "AppDelegate.h"
@interface BookTableViewController ()<NSFetchedResultsControllerDelegate>
@property(strong,nonatomic)NSFetchedResultsController *fetchedRC;
@property(strong,nonatomic)NSManagedObjectContext *managedObjectContext;
@end @implementation BookTableViewController - (void)viewDidLoad {
[super viewDidLoad];
//获取应用代理
AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
//本次案例需要对CoreData的内容进行修改,涉及到managedObjectContext,但是magagedObjetContext属于Appdelegate的属性,此处使用协议获取创建新的managedObjectContext;
self.managedObjectContext = delegate.managedObjectContext;
//使用fetchedRC获取数据
NSError *error = nil;
[self.fetchedRC performFetch:&error];
if (error) {
NSLog(@"NSFetchedResultsController获取数据失败");
}
}
-(NSFetchedResultsController *)fetchedRC
{
//判断fetchRC是否存在,如果不存在则创建新的,否则直接返回
if (!_fetchedRC) {
//使用NSFetchRequest进行获取数据
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Book class])];
request.fetchBatchSize = ;
//设置以某个字段进行排序,此案例以:price价格大小进行排序
NSSortDescriptor *priceSort = [NSSortDescriptor sortDescriptorWithKey:@"price" ascending:YES];
//对获取的数据进行排序
[request setSortDescriptors:@[priceSort]];
//创建新的fetchedRC
_fetchedRC = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
_fetchedRC.delegate = self;
}
return _fetchedRC;
} #pragma mark - Table view data source
//设置tableView的分组数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//分组的数据取决于创建sectionNameKeyPath的设置;
return self.fetchedRC.sections.count;
}
//设置tableView每组有多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id sectionsInfo = [self.fetchedRC.sections objectAtIndex:section];
return [sectionsInfo numberOfObjects];
}
//自定义方法,设置单元格的显示内容
-(void)configCell:(UITableViewCell *)cell andIndexPath:(NSIndexPath *)indexPath
{
//获取选中的对象
Book *book = [self.fetchedRC objectAtIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:@"%@ %@",book.title,book.author];
cell.detailTextLabel.text = [NSString stringWithFormat:@"%@",book.price];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//1.根据reuseindentifier先到对象池中去找重用的单元格
static NSString *reuseIndetifier = @"bookCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIndetifier];
//2.如果没有找到需要自己创建单元格对象
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIndetifier];
}
//3.设置单元格对象的内容
[self configCell:cell andIndexPath:indexPath];
return cell;
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete)
{
Book *book = [self.fetchedRC objectAtIndexPath:indexPath];
//1.先删除CoreData中的相应数据
[self.managedObjectContext deleteObject:book];
//插入新的记录
AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
[delegate addBookWithTitle:@"唐诗三百首" andAuthor:@"李白等" andPrice:@12.3];
book.price = @([book.price doubleValue]+);
NSError *error = nil;
[self.managedObjectContext save:&error];
if(error) {
NSLog(@"失败");
}
} else if (editingStyle == UITableViewCellEditingStyleInsert)
{
}
}
#pragma mark - NSFetchedResultsController代理方法
-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}
/**
* 以下方法共进行了两项操作:
1.判断操作的类型
2.对修改的数据、或新插入的数据位置进行局部刷新
*/
-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
if (type == NSFetchedResultsChangeDelete)//删除操作
{
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
else if (type == NSFetchedResultsChangeInsert)//插入操作
{
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
else if (type == NSFetchedResultsChangeUpdate)//更新操作
{
//首先获取cell;
UITableViewCell *cell = [self.fetchedRC objectAtIndexPath:indexPath];
//调用configCell方法
[self configCell:cell andIndexPath:indexPath];
//重新加载指定行
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
@end
运行结果,如下图:
创建控制器

一般来说,你会创建一个NSFetchedResultsController实例作为tableview的成员变量。初始化的时候,你提供四个参数:

1。 一个fetchrequest.必须包含一个sortdescriptor用来给结果集排序。

2。 一个managedobject context。 控制器用这个context来执行取数据的请求。

3。 一个可选的keypath作为sectionname。控制器用keypath来把结果集拆分成各个section。(传nil代表只有一个section)

4。 一个cachefile的名字,用来缓冲数据,生成section和索引信息。
 
案例中:代码解析
使用fethedRequestController控制器获取数据,此处使用懒加载的方式读取数据:
_fetchedRC = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:self.managedObjectContent sectionNameKeyPath:nil cacheName:@"book"];
参数解析:
参数1 :使用之前需通过NSFetchRequest进行读取数据,然后对request进行排序操作(必须排序你懂不?不排序就出错)。
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Book class])];
        //初始化fetchedRC必须要排序
        request.fetchBatchSize = 20;
        NSSortDescriptor *priceSort = [NSSortDescriptor sortDescriptorWithKey:@"price" ascending:YES];
        [request setSortDescriptors:@[priceSort]];
参数2:由于managedObjectContent是在Applelegate.h文件中,如果想要使用,需通过Application协议创建新的managedObjectContent。
//获取应用程序代理
    AppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
    //如果要对上下文内容进行修改,可managedObjectContent存在于Appdelegate中,须通过协议进行引用。
    self.managedObjectContent = appDelegate.managedObjectContext;
参数3:在tableView中如果不准备进行分组显示,可以将值设为:nil;
参数4:设置缓存。
 

NSFetchedResultController与UITableView的更多相关文章

  1. iOS UITableView 与 UITableViewController

    很多应用都会在界面中使用某种列表控件:用户可以选中.删除或重新排列列表中的项目.这些控件其实都是UITableView 对象,可以用来显示一组对象,例如,用户地址薄中的一组人名.项目地址. UITab ...

  2. UITableView(二)

    #import "ViewController.h" @interface ViewController () @end @implementation ViewControlle ...

  3. iOS: 在UIViewController 中添加Static UITableView

    如果你直接在 UIViewController 中加入一个 UITableView 并将其 Content 属性设置为 Static Cells,此时 Xcode 会报错: Static table ...

  4. iOS 编辑UITableView(根据iOS编程编写)

    上个项目我们完成了 JXHomepwner 简单的应用展示,项目地址.本节我们需要在上节项目基础上,增加一些响应用户操作.包括添加,删除和移动表格. 编辑模式 UITableView 有一个名为  e ...

  5. 使用Autolayout实现UITableView的Cell动态布局和高度动态改变

    本文翻译自:stackoverflow 有人在stackoverflow上问了一个问题: 1 如何在UITableViewCell中使用Autolayout来实现Cell的内容和子视图自动计算行高,并 ...

  6. iOS - UITableView中Cell重用机制导致Cell内容出错的解决办法

    "UITableView" iOS开发中重量级的控件之一;在日常开发中我们大多数会选择自定Cell来满足自己开发中的需求, 但是有些时候Cell也是可以不自定义的(比如某一个简单的 ...

  7. UITableView cell复用出错问题 页面滑动卡顿问题 & 各杂七杂八问题

    UITableView 的cell 复用机制节省了内存,但是有时对于多变的自定义cell,重用时会出现界面出错(例如复用出错,出现cell混乱重影).滑动卡顿等问题,这里只简单敲下几点复用出错时的解决 ...

  8. UITableview delegate dataSource调用探究

    UITableview是大家常用的UIKit组件之一,使用中我们最常遇到的就是对delegate和dataSource这两个委托的使用.我们大多数人可能知道当reloadData这个方法被调用时,de ...

  9. UITableView点击每个Cell,Cell的子内容的收放

    关于点击TableviewCell的子内容收放问题,拿到它的第一个思路就是, 方法一: 运用UITableview本身的代理来处理相应的展开收起: 1.代理:- (void)tableView:(UI ...

随机推荐

  1. Unity与Android交互实现

    主要参考了这篇文章: Unity与Android交互方案优化版 链接:https://www.jianshu.com/p/86b275da600e 自己的实现(unity获取内存和温度): andro ...

  2. 如何通过PHP判断年份是否是闰年----两种方法

    1.定义:闰年是对4取余为0,对100取余不等于0,对400取余等于0的年是闰年. 2.代码: 第一种方法:直接函数判断 $day = date('Y'); if ($day%4==0&&am ...

  3. python3 - 动态添加属性以及方法

    给实例动态添加方法,需引入types模块,用其的MethodType(要绑定的方法名,实例对象)来进行绑定:给类绑定属性和方法,可以通过 实例名.方法名(属性名) = 方法名(属性值) 来进行绑定.给 ...

  4. encodeURI() 函数概述

    encodeURI() 函数的作用是将URI中的某些特定的字符以一位到四位的转义序列来替代,这些转义序列就是这些字符的UTF-8编码(如果说某些字符是由两个代替字符构成的,该字符也只会是四位的转义序列 ...

  5. java.lang.VerifyError: Expecting a stack map frame

    https://blog.csdn.net/u013066244/article/details/78434134 对于java7而言,需要添加 -XX:-UseSplitVerifier(已实践). ...

  6. grafana-----Annotation

    注释提供了一个方法,在丰富的活动中做个标志点.当你鼠标移到这个注释上,你可以得到title,tags,和text information的事件. Queries 注释事件获得是通过一个注释查询.打开d ...

  7. Sql注入基础_mysql注入

    Mysql数据库结构 数据库A 表名 列名 数据 数据库B 表名 列名 数据 Mysql5.0以上自带数据库:information_schema information_schema:存储mysql ...

  8. 任务04——对四则运算小程序的进一步改进,并学习 Git 中 Branch 的用法

    https://github.com/jinxiaohang/Operation/tree/test01 对于任务2的代码进行优化修改感觉很麻烦,所以直接选择重写代码完成任务四, 任务四很早就发布了, ...

  9. QCache 缓存(模板类,类似于map,逻辑意义上的缓存,方便管理,和CPU缓存无关。自动获得被插入对象的所有权,超过一定数量就会抛弃某些值)

    在软件开发中,我们经常需要在内存中存储一些临时数据用于后续相关计算.我们一般把这些数据存储到某个数组里,或者STL中的某个合适的容器中.其实,在Qt中直接为我们提供了一个QCache类专用于这种需求. ...

  10. [HEOI2014]南园满地堆轻絮

    [HEOI2014]南园满地堆轻絮 BZOJ luogu 二分答案贪心check 首先b[1]最小一定优 之后就贪心的最小化b[i]就行 #include<bits/stdc++.h> u ...