2011年9月9日 星期五

Lala's Program Note 實作記錄: 11. 為文章列表加上 NSFetchedResultsController

since: 2011/09/09
update: 2011/09/09


A. 為文章列表(ArticleList) 加上 NSFetchedResultsController
   1. 修改 ArticleListViewController.h 如下:
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>

//@interface ArticleListViewController : UITableViewController
@interface ArticleListViewController : UITableViewController <NSFetchedResultsControllerDelegate> {

    NSFetchedResultsController *fetchedResultsController;
    NSManagedObjectContext *managedObjectContext;
    //@for relationship used
    NSManagedObject *noteBook;

}

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) NSManagedObject *noteBook;

@end

---------------------------------------------------------------------------------------------------------------

   2. 修改 ArticleListViewController.m 如下:
@synthesize fetchedResultsController, managedObjectContext, noteBook;

- (void)dealloc {
    [fetchedResultsController release];
    [managedObjectContext release];
    [noteBook release];
    [super dealloc];
}

---------------------------------------------------------------------------------------------------------------

   3. 在 ArticleListViewController.m 建立 Fetched Results Controller
#pragma mark -
#pragma mark Fetched results controller
// Creating the Fetched Results Controller:
// Do it in the accessor for the fetchedResultsController member
- (NSFetchedResultsController *)fetchedResultsController {
    if (fetchedResultsController != nil) {
        return fetchedResultsController;
    }
   
    // Create the fetch request for the entity
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
   
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"NoteArticle" inManagedObjectContext:self.managedObjectContext];
   
    [fetchRequest setEntity:entity];
   
    // Set the batch size
    [fetchRequest setFetchBatchSize:10];
   
    // sort by noteBook name, ascending
    // * with Fetched Results Controller, you must have at least one sort descriptor.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
   
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
   
    [fetchRequest setSortDescriptors:sortDescriptors];
   
    // for relationship
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"notebook == %@", self.noteBook];

    [fetchRequest setPredicate:predicate];
   
    // Create the fetched results controller using the fetch request we just created,
    // and with the managed object context member,
    // and set this controller to be the delegate
    // * we pass nil for the sectionNameKeyPath parameter,
    //   because we have no sections.
   
    // **** 若將 cacheName 設為 @"NoteArticle", 會出現以下的錯誤訊息; 因此將 cacheName 設為 nil ****
    /*
       currFATAL ERROR The persistent cache of section information does not match the ent configuration You have illegally mutated the NSFetchedResultsController's fetch request its predicate or its sort descriptor without either disabling caching
     */
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
   
    // set ArticleListViewController be aFetchedResultsController's delegate
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;
   
    // Clean up
    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];
   
    // Fetch the results into the fetched results controller
    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {
        //TODO
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
   
    return fetchedResultsController;
}

---------------------------------------------------------------------------------------------------------------

   4. 修改 NoteBookViewController.m 檔案
-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {

    //ArticleListViewController *articleListViewController = [[ArticleListViewController alloc] init];

    ArticleListViewController *articleListViewController = [[ArticleListViewController alloc] initWithStyle:UITableViewStylePlain];

    // set controller's managed object context member right after initializing
    articleListViewController.managedObjectContext = self.managedObjectContext;

    NSManagedObject *noteBook = [[self fetchedResultsController] objectAtIndexPath:indexPath];

    articleListViewController.title = [NSString stringWithFormat:@"%@",[noteBook valueForKey:@"name"]];

    //@add for relationship used
    articleListViewController.noteBook = noteBook;

    //@update
    // not need to Wrap it in an instance of UINavigationController, just do:
    [self.navigationController pushViewController:articleListViewController animated:YES];

    [articleListViewController release];
}

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。