Iphone 如何正确配置NSFetchedResultsController

Iphone 如何正确配置NSFetchedResultsController,iphone,core-data,Iphone,Core Data,我在代码中放置了一个NSFetchedResultsController,这样就可以很好地自动分割表视图数据 因此,我正在运行一个测试,以确保一切正常工作。我的持久存储中只有一个Book实体。我将首先以旧的方式执行获取,然后尝试使用NSFetchedResultsController。两个代码块之间的差异只有两行 不带NSFetchedResultsController的代码: NSFetchRequest *request = [[NSFetchRequest alloc] init];

我在代码中放置了一个NSFetchedResultsController,这样就可以很好地自动分割表视图数据

因此,我正在运行一个测试,以确保一切正常工作。我的持久存储中只有一个Book实体。我将首先以旧的方式执行获取,然后尝试使用NSFetchedResultsController。两个代码块之间的差异只有两行

不带NSFetchedResultsController的代码:

 NSFetchRequest *request = [[NSFetchRequest alloc] init];
 NSEntityDescription *entity = [NSEntityDescription entityForName:kBookEntityName inManagedObjectContext:self.managedObjectContext];
 [request setEntity:entity];

 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:NO];
 NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
 [request setSortDescriptors:sortDescriptors];
 [sortDescriptor release];
 [sortDescriptors release];

  //The following 2 lines will be replaced by the NSFetchedResultsController
 NSMutableArray *mutableFetchResults = [[[self.managedObjectContext executeFetchRequest:request error:nil] mutableCopy] autorelease];
 Book *result = (Book*)[mutableFetchResults objectAtIndex:0];

 NSString* title = [result valueForKey:@"title"];
 NSString* priority = [result valueForKeyPath:@"priority.name"];


 [request release];
NSFetchedResultsController* fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"title" cacheName:@"BookList"];                                                                                                                                                                                                                                                                                                           

Book *result = (Book*)[fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
现在,我在以下行中替换NSFetchedResultsController:

 NSFetchRequest *request = [[NSFetchRequest alloc] init];
 NSEntityDescription *entity = [NSEntityDescription entityForName:kBookEntityName inManagedObjectContext:self.managedObjectContext];
 [request setEntity:entity];

 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:NO];
 NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
 [request setSortDescriptors:sortDescriptors];
 [sortDescriptor release];
 [sortDescriptors release];

  //The following 2 lines will be replaced by the NSFetchedResultsController
 NSMutableArray *mutableFetchResults = [[[self.managedObjectContext executeFetchRequest:request error:nil] mutableCopy] autorelease];
 Book *result = (Book*)[mutableFetchResults objectAtIndex:0];

 NSString* title = [result valueForKey:@"title"];
 NSString* priority = [result valueForKeyPath:@"priority.name"];


 [request release];
NSFetchedResultsController* fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"title" cacheName:@"BookList"];                                                                                                                                                                                                                                                                                                           

Book *result = (Book*)[fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
看起来很枯燥。第一个代码块正确地获取单个Book实体。但是,带有NSFetchedResultsController的代码没有。相反,它返回nil

我的问题是:在本例中,我是否正确配置了NSFetchedResultsController


(注意,NSFetchedResultsController的fetchedObjects属性也为零)

我认为您仍然需要告诉
NSFetchedResultsController
以实际执行提取:

NSError *error;
BOOL success = [controller performFetch:&error];
(摘自
NSFetchedResultsController
参考中的示例)


另一件看起来很奇怪的事情是:您真的想使用“title”作为
sectionNameKeyPath
?这基本上不会为每本书创建一个单独的部分吗?

您只需要初始化NSFetchedResultsController一次,如下所示

NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
在控制器的标头中声明,并且managedObjectContext已正确初始化

- (void)viewDidLoad {

    [super viewDidLoad];

    NSError *error;
    if (![[self fetchedResultsController] performFetch:&error]) {
        // Handle error
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

    }

    NSLog(@"%d objects fetched", [[fetchedResultsController fetchedObjects] count]);
}

- (NSFetchedResultsController *)fetchedResultsController {

    if (fetchedResultsController != nil) {
        return fetchedResultsController;

    }

    /*
     Set up the fetched results controller.
     */



    // Create the fetch request for the entity.
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:kBookEntityName inManagedObjectContext:self.managedObjectContext];
    [request setEntity:entity];

/* Optional settings

    [request setResultType:NSManagedObjectResultType];
    [request setIncludesPropertyValues:YES];
    [request setIncludesPendingChanges:NO];
    [request setReturnsObjectsAsFaults:NO];
*/  


    // Edit the sort key as appropriate.
     NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:NO];
 NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
 [request setSortDescriptors:sortDescriptors];
 [sortDescriptor release];
 [sortDescriptors release];;

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:@"title" cacheName:@"BookList"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    [aFetchedResultsController release];
    [request release];


    return fetchedResultsController;
}    

“title”组织只是一个让它启动并运行的测试。实际上,我想按作者姓名上的键路径进行分段,但我想用一个简单的示例来实现它。很遗憾,我没有实际执行提取。我不知道为什么我会认为提取是在初始化时执行的。谢谢