FetchedResultsController-03-CoreData相关

//
//  EditViewController.m
//  03_FetchedResultsController
//
//  Created by JayWon on 15/10/13.
//  Copyright (c) 2015年 JayWon. All rights reserved.
//

#import "EditViewController.h"
#import "Student.h"
#import "DBManager.h"

@interface EditViewController ()
{
    __weak IBOutlet UITextField *nameTF;
    __weak IBOutlet UITextField *studNoTF;
    __weak IBOutlet UISegmentedControl *lessonSgmtCtrl;
}

@end

@implementation EditViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveAction)];
}

-(void)saveAction
{
        //(1)判断输入数据的有效性
    if (nameTF.text.length == 0 || studNoTF.text.length == 0) {
        
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"警告" message:@"信息不完整" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *action = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:nil];
        [alert addAction:action];
        [self presentViewController:alert animated:YES completion:nil];
        
        return;}
    
        //(2)创建Student对象,把Student添加到context上。
    Student *stud = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:[DBManager shareManager].managedObjectContext];
    stud.name = nameTF.text;
    stud.no = studNoTF.text;
    
    stud.lesson = [lessonSgmtCtrl titleForSegmentAtIndex:lessonSgmtCtrl.selectedSegmentIndex];
    
        //(3)同步到数据库
    [[DBManager shareManager] saveContext];

        //(4)回到学生信息列表界面
    [self.navigationController popViewControllerAnimated:YES];
}

//回收键盘
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [self.view endEditing:YES];
}

@end
//
//  ListTableViewController.m
//  03_FetchedResultsController
//
//  Created by JayWon on 15/10/13.
//  Copyright (c) 2015年 JayWon. All rights reserved.
//

#import "ListTableViewController.h"
#import "DBManager.h"
#import "Student.h"

@interface ListTableViewController () <NSFetchedResultsControllerDelegate>
@end

@implementation ListTableViewController {
    
    NSFetchedResultsController *_fetchedCtrl;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
   [self configFetchedCtroller];
}

- (void)configFetchedCtroller {
    
    if (_fetchedCtrl) {
        return;
    }
    
    //1.设置查询对象
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
    
    //2.设置tableView中每条数据的显示规则,升序或者降序,可以依据数据库中某一个字段来作为排序标准。
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"no" ascending:YES];
    
    request.sortDescriptors = @[sort];
    
    //3.fetchCtrl的作用是初始化tableView的数据源。
    //request的作用是表示显示数据库中哪一个表中的数据
    //sectionNameKeyPath参数的作用是表示以表中哪一个字段的内容进行分组显示
    _fetchedCtrl = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[DBManager shareManager].managedObjectContext sectionNameKeyPath:@"lesson" cacheName:nil];
    
    //5.设置代理来监听context中数据的变化
    _fetchedCtrl.delegate = self;
    
    //4.设置其开始工作,响应context的变化,并把此变化反馈到tableView上。
    [_fetchedCtrl performFetch:nil];
}

#pragma mark - Table view data source
/**
 *  1.返回section个数
 */
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return _fetchedCtrl.sections.count;
}
/**
 *  2.返回row个数
 */
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
     //获取到组对象
    id<NSFetchedResultsSectionInfo> result = _fetchedCtrl.sections[section];

    return [result numberOfObjects];
}
/**
 *  3.返回cell内容
 */
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"kListCellID"];
    
    Student *stud = [_fetchedCtrl objectAtIndexPath:indexPath];
    cell.textLabel.text = stud.name;
    cell.detailTextLabel.text = stud.no;
    return cell;
}

#pragma mark - section title
/**
 *  //1.返回组头视图的标题
 */
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    id<NSFetchedResultsSectionInfo> result = _fetchedCtrl.sections[section];
    return [result name];
}
/**
 *  2.侧边栏内容
 */
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    NSArray *sections = _fetchedCtrl.sections;
    NSMutableArray *nameArray = [[NSMutableArray alloc] initWithCapacity:sections.count];
    for (id<NSFetchedResultsSectionInfo> result in sections) {
        
        [nameArray addObject:[result name]];
    }
    
    return nameArray;
}



#pragma mark - delete
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
    return UITableViewCellEditingStyleDelete;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        
        //1.获取到Student对象
        Student *stu = [_fetchedCtrl objectAtIndexPath:indexPath];
        
        //2.从context上删除
        [[DBManager shareManager].managedObjectContext deleteObject:stu];
        //3.同步到数据库
        [[DBManager shareManager] saveContext];
    }
}

#pragma mark - NSFetchedResultsControllerDelegate
/**
 *  //1.数据变化时调用(对context做增删改移动后会调用)
 */
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(nullable NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(nullable NSIndexPath *)newIndexPath {
    
    switch (type) {
        case NSFetchedResultsChangeInsert:
            
            [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            
            break;
        case NSFetchedResultsChangeDelete :
            [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        default:
            break;
    }

}
/**
 *  //2.当数据变化引起分区变化时调用
 */
- (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;
            
        default:
            break;
    }

}

/**
 *  //3.数据将要变化时调用
 */
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
   
    [self.tableView beginUpdates];
}
/**
 *  //4.数据已经变化后调用
 */
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    
    [self.tableView endUpdates];
}


@end
//
//  DBManager.m
//  03_FetchedResultsController
//
//  Created by kangkathy on 15/12/4.
//  Copyright © 2015年 JayWon. All rights reserved.
//

#import "DBManager.h"

@implementation DBManager


+ (instancetype)shareManager {
    
    static DBManager *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[super allocWithZone:nil] init];
    });
    
    return instance;
}

-(id)copy {
    return self;
}

+(instancetype)allocWithZone:(struct _NSZone *)zone {
    return [self shareManager];
}


#pragma mark - Core Data stack

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

//返回沙盒路径下的Documents文件夹
- (NSURL *)applicationDocumentsDirectory {
    
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

- (NSManagedObjectModel *)managedObjectModel {
    
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    //程序包中的模型文件扩展名会自动变成momd。
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Student" withExtension:@"momd"];
    
    //对象模型是通过模型文件来构造的。
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }
    
    //PSC是根据模型文件创建的。
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Student.sqlite"];

   
    [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:nil];
    return _persistentStoreCoordinator;
}


- (NSManagedObjectContext *)managedObjectContext {

    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    
    //context与PSC对象关联起来,绑定PSC对象的目的是使Context和外部的存储文件联系起来。
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;
}

#pragma mark - Core Data Saving support

//对Context保存,即和外部的数据库文件同步。
- (void)saveContext {
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {        
        //save操作表示同步。把context上的MO数据同步到数据库中。
        if ([managedObjectContext hasChanges])
        {
            [managedObjectContext save:nil];
        }
    }
}





@end
//
//  DBManager.h
//  03_FetchedResultsController
//
//  Created by kangkathy on 15/12/4.
//  Copyright © 2015年 JayWon. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@interface DBManager : NSObject

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

+ (instancetype)shareManager;


@end
时光见证了成长,还很无知,我想一点点幼稚转为有知!
原文地址:https://www.cnblogs.com/foreveriOS/p/5470458.html