//
// RootViewController.m
// FetchedResultsController
//
// Created by 何瑾 on 15/1/16.
// Copyright (c) 2015年 e世雕龙. All rights reserved.
//
#import "RootViewController.h"
#import "Student.h"
@interface RootViewController ()
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;// 托管对象上下文
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;// 抓取结果控制器
@end
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 1、获取应用程序对象(单例)
UIApplication *app = [UIApplication sharedApplication];
// 2、获取应用程序委托
id appDelegate = app.delegate;
// 3、获取托管对象上下文
self.managedObjectContext = [appDelegate managedObjectContext];
// 4、创建抓取请求对象
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
// 4.1、创建排序规则
NSSortDescriptor *sd1 = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
// 4.2、设置抓取请求对象的排序规则属性
[request setSortDescriptors:@[sd1]];
// 5、创建抓取结果控制器(1、给表视图提供数据。2、监控CoreData数据变化,回调四个委托方法)
self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"stu"];
// 5.1指定抓取结果控制器的委托,在CoreData中对象发生变化时调用相关委托方法
self.fetchedResultsController.delegate = self;
// 6、执行抓取
__autoreleasing NSError *error = nil;
[self.fetchedResultsController performFetch:&error];
if (error) {
[self myAlert:[error localizedDescription]];
}
}
#pragma mark 通过CoreData添加对象
- (IBAction)addObject:(id)sender {
//使用实体描述对象把一个空的数据模型(托管对象)放入托管对象上下文中
Student *stu = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:self.managedObjectContext];
//设置托管对象属性值
static int i = 0;
i++;
stu.name = [NSString stringWithFormat:@"何瑾%d",i];
stu.phoneNumber = @18888888888;
//保存托管对象上下文
__autoreleasing NSError *error = nil;
[self.managedObjectContext save:&error];
if (error) {
NSLog(@"%@",[error localizedDescription]);
[self myAlert:[error localizedDescription]];
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[self.fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
if ([[self.fetchedResultsController sections] count] > 0) {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
} else
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 创建出列可重用标识符
static NSString *cellID = @"cellID";
// 从出列可重用队列中获取单元格
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
// 如果没有则创建
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
}
Student *stu = [self.fetchedResultsController objectAtIndexPath:indexPath];
// Configure the cell with data from the managed object.
cell.textLabel.text = stu.name;
cell.detailTextLabel.text = [stu.phoneNumber stringValue];
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) {
// Delete the row from the data source
// 只需要删除CoreData中对象
// 从CoreData的托管对象上下文中获取模型对象
Student *stu = [self.fetchedResultsController objectAtIndexPath:indexPath];
// 从CoreData的托管对象上下文中删除对象
[self.managedObjectContext deleteObject:stu];
// 保存上下文
__autoreleasing NSError *error = nil;
[self.managedObjectContext save:&error];
if (error) {
[self myAlert:[error localizedDescription]];
}
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#pragma Table view delegate
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
return @"删除";
}
#pragma mark 封装UIAlertView
- (void)myAlert:(NSString *)errorMsg {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"信息" message:errorMsg delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
[alert show];
}
#pragma mark NSFetchedResultsControllerDelegate methods
/*
Assume self has a property 'tableView' -- as is the case for an instance of a UITableViewController
subclass -- and a method configureCell:atIndexPath: which updates the contents of a given cell
with information from a managed object at the given index path in the fetched results controller.
*/
// 告知tableView开始进行数据变化,此时tableView将会记录变化点,当所有变化结束之后,统一进行UI的刷新
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
// 表视图分区变化回调此委托方法
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
// 根据CoreData数据变化类型进行表视图更新(增、删、改、移动)
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
// 增加
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
// 删除
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
// 修改
case NSFetchedResultsChangeUpdate:
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
// 移动
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
// 通知tableView数据变化结束,开始进行UI刷新
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
@end