zoukankan      html  css  js  c++  java
  • NSFetchedResultController与UITableView


    1
    #import "AppDelegate.h" 2 #import "Book.h" 3 @interface AppDelegate () 4 @end 5 @implementation AppDelegate 6 -(void)addBookWithTitle:(NSString *)title andAuthor:(NSString *)author andPrice:(NSNumber *)price 7 { 8 Book *book = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Book class]) inManagedObjectContext:self.managedObjectContext]; 9 book.title = title; 10 book.author = author; 11 book.price = price; 12 } 13 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 14 //如果不想每次执行时测试数据都重新插入一遍,可以使用偏好设置,如果已经存在了,就不再进行插入了。 15 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 16 BOOL isInserted = [userDefaults boolForKey:@"inInserted"]; 17 if (!isInserted) 18 { 19 //插入数据 20 [self addBookWithTitle:@"*文*" andAuthor:@"" andPrice:@10000.1]; 21 [self addBookWithTitle:@"西游记" andAuthor:@"吴承恩" andPrice:@20.5]; 22 [self addBookWithTitle:@"水浒传" andAuthor:@"施耐庵" andPrice:@5.1]; 23 [self addBookWithTitle:@"三国演义" andAuthor:@"罗贯中" andPrice:@10.2]; 24 [self addBookWithTitle:@"史记" andAuthor:@"司马迁" andPrice:@45.3]; 25 [self addBookWithTitle:@"资治通鉴" andAuthor:@"司马光" andPrice:@56.5]; 26 [self saveContext]; 27 //保存偏好设置 28 [userDefaults setBool:YES forKey:@"inInserted"]; 29 //自动步更新 30 [userDefaults synchronize]; 31 } 32 return YES; 33 }
      1 #import "BookTableViewController.h"
      2 #import "Book.h"
      3 #import "AppDelegate.h"
      4 @interface BookTableViewController ()<NSFetchedResultsControllerDelegate>
      5 @property(strong,nonatomic)NSFetchedResultsController *fetchedRC;
      6 @property(strong,nonatomic)NSManagedObjectContext *managedObjectContext;
      7 @end
      8 
      9 @implementation BookTableViewController
     10 
     11 - (void)viewDidLoad {
     12     [super viewDidLoad];
     13     //获取应用代理
     14     AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
     15     //本次案例需要对CoreData的内容进行修改,涉及到managedObjectContext,但是magagedObjetContext属于Appdelegate的属性,此处使用协议获取创建新的managedObjectContext;
     16     self.managedObjectContext = delegate.managedObjectContext;
     17     //使用fetchedRC获取数据
     18     NSError *error = nil;
     19     [self.fetchedRC performFetch:&error];
     20     if (error) {
     21         NSLog(@"NSFetchedResultsController获取数据失败");
     22     }
     23 }
     24 -(NSFetchedResultsController *)fetchedRC
     25 {
     26     //判断fetchRC是否存在,如果不存在则创建新的,否则直接返回
     27     if (!_fetchedRC) {
     28         //使用NSFetchRequest进行获取数据
     29         NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Book class])];
     30         request.fetchBatchSize = 20;
     31         //设置以某个字段进行排序,此案例以:price价格大小进行排序
     32         NSSortDescriptor *priceSort = [NSSortDescriptor sortDescriptorWithKey:@"price" ascending:YES];
     33         //对获取的数据进行排序
     34         [request setSortDescriptors:@[priceSort]];
     35         //创建新的fetchedRC
     36         _fetchedRC = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
     37         _fetchedRC.delegate = self;
     38     }
     39     return _fetchedRC;
     40 }
     41 
     42 #pragma mark - Table view data source
     43 //设置tableView的分组数
     44 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
     45 {
     46     //分组的数据取决于创建sectionNameKeyPath的设置;
     47     return self.fetchedRC.sections.count;
     48 }
     49 //设置tableView每组有多少行
     50 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
     51     id sectionsInfo = [self.fetchedRC.sections objectAtIndex:section];
     52     return [sectionsInfo numberOfObjects];
     53 }
     54 //自定义方法,设置单元格的显示内容
     55 -(void)configCell:(UITableViewCell *)cell andIndexPath:(NSIndexPath *)indexPath
     56 {
     57     //获取选中的对象
     58     Book *book = [self.fetchedRC objectAtIndexPath:indexPath];
     59     cell.textLabel.text = [NSString stringWithFormat:@"%@ %@",book.title,book.author];
     60     cell.detailTextLabel.text = [NSString stringWithFormat:@"%@",book.price];
     61 }
     62 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
     63 {
     64     //1.根据reuseindentifier先到对象池中去找重用的单元格
     65     static NSString *reuseIndetifier = @"bookCell";
     66     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIndetifier];
     67     //2.如果没有找到需要自己创建单元格对象
     68     if (cell == nil) {
     69         cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIndetifier];
     70     }
     71     //3.设置单元格对象的内容
     72     [self configCell:cell andIndexPath:indexPath];
     73     return cell;
     74 }
     75 // Override to support conditional editing of the table view.
     76 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
     77     // Return NO if you do not want the specified item to be editable.
     78     return YES;
     79 }
     80 // Override to support editing the table view.
     81 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
     82     if (editingStyle == UITableViewCellEditingStyleDelete)
     83     {
     84         Book *book = [self.fetchedRC objectAtIndexPath:indexPath];
     85         //1.先删除CoreData中的相应数据
     86         [self.managedObjectContext deleteObject:book];
     87         //插入新的记录
     88         AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
     89         [delegate addBookWithTitle:@"唐诗三百首" andAuthor:@"李白等" andPrice:@12.3];
     90         book.price = @([book.price doubleValue]+10);
     91         NSError *error = nil;
     92         [self.managedObjectContext save:&error];
     93         if(error) {
     94             NSLog(@"失败");
     95         }
     96     } else if (editingStyle == UITableViewCellEditingStyleInsert)
     97     {
     98     }
     99 }
    100 #pragma mark - NSFetchedResultsController代理方法
    101 -(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
    102 {
    103     [self.tableView beginUpdates];
    104 }
    105 -(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
    106 {
    107     [self.tableView endUpdates];
    108 }
    109 /**
    110  * 以下方法共进行了两项操作:
    111     1.判断操作的类型
    112     2.对修改的数据、或新插入的数据位置进行局部刷新
    113  */
    114 -(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
    115 {
    116     if (type == NSFetchedResultsChangeDelete)//删除操作
    117     {
    118         [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    119     }
    120     else if (type == NSFetchedResultsChangeInsert)//插入操作
    121     {
    122         [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    123     }
    124     else if (type == NSFetchedResultsChangeUpdate)//更新操作
    125     {
    126         //首先获取cell;
    127         UITableViewCell *cell = [self.fetchedRC objectAtIndexPath:indexPath];
    128         //调用configCell方法
    129         [self configCell:cell andIndexPath:indexPath];
    130         //重新加载指定行
    131         [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    132     }
    133 }
    134 @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:设置缓存。
     
  • 相关阅读:
    git命令
    Linux基础知识手册
    Linux系统编程
    A
    Subsequences in Substrings Kattis
    G
    K
    K
    C
    E
  • 原文地址:https://www.cnblogs.com/xjf125/p/4829350.html
Copyright © 2011-2022 走看看