提问



我正在尝试实现一个具有2个UITableViews(在iPad上)的UIViewController:一个用于显示清单的各个部分,另一个用于显示所选/部分中的问题。


我已经设置了NSFetchedResultsController并且我能够从持久存储中成功获取对象,但是没有调用NSFetchedResultsController或UITableView委托方法。


我设置类来实现相应的协议,并将FRC和TableView委托设置为self。


我已经在每个委托方法中放置断点但从未到达任何一个(是的,我在启用断点的情况下运行,并且可以逐步完成代码的其他部分)。


我感谢任何有关为什么在这些情况下不会调用委托方法的见解:
1)执行[[FRC performFetch]]并设置/更新FRC.fetchedObjects时
2)调用[[tableView reloadData]]时(至少应检查numberOfSectionsInTableView?)


.H文件:


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


@interface ChecklistViewController : UIViewController <NSFetchedResultsControllerDelegate,
                                                        UITableViewDelegate,
                                                        UITableViewDataSource> 
{
    UIView *sectionsView;

    UITableViewController       *sectionsTable;
    NSFetchedResultsController  *sectionsFetchedResultsController;
}

@property (nonatomic, retain) IBOutlet  UIView                      *sectionsView;
@property (nonatomic, retain) IBOutlet  UITableViewController       *sectionsTable;
@property (nonatomic, retain)           NSFetchedResultsController  *sectionsFetchedResultsController;

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;

@end


.M文件


#import "ChecklistViewController.h"
#import "Inspection.h"
#import "InspectionQuestion.h"
#import "ContextManager.h"


@implementation ChecklistViewController

@synthesize sectionsView;
@synthesize sectionsTable;
@synthesize sectionsFetchedResultsController;

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}



#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    //Setup tableviews
    self.sectionsTable = [**UITableViewController alloc] init]; 
    self.sectionsTable.view = self.sectionsView;
    self.sectionsTable.tableView.dataSource = self;         
    self.sectionsTable.tableView.delegate = self;     

    //Fetch sections
    NSError *error = nil;
    if (self.sectionsFetchedResultsController.fetchedObjects == nil) {
        self.sectionsFetchedResultsController.delegate = self;
        if (![**self sectionsFetchedResultsController] performFetch:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }       
    }
    NSLog(@"fetched results:%@",self.sectionsFetchedResultsController.fetchedObjects);

    //For testing delegates
    [self.sectionsTable.tableView reloadData];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return YES;
}


#pragma mark -
#pragma mark TableViewDelegate methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    NSInteger count = [**self.sectionsFetchedResultsController sections] count];

    if (count == 0) {
        count = 1;
    }

    return count;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSInteger numberOfRows = 0;

    if ([**self.sectionsFetchedResultsController sections] count] > 0) {
        id <NSFetchedResultsSectionInfo> sectionInfo = [**self.sectionsFetchedResultsController sections] objectAtIndex:section];
        numberOfRows = [sectionInfo numberOfObjects];
    }

    NSLog(@"CheckListViewController::numberOfRowsInSection - numberOfRows:%d", numberOfRows);
    return numberOfRows;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // Dequeue or if necessary create a TableViewCell, then set its  to the  for the current row.           
    static NSString *cellIdentifier = @"cellIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [**UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }

    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}


- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    // Configure the cell
    NSLog(@"CheckListViewController::configureCell - indexPath:%@,", indexPath);        
    InspectionQuestion *question = [self.sectionsFetchedResultsController objectAtIndexPath:indexPath];    
}



- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"CheckListViewController::didSelectRowAtIndexPath - started");
    InspectionQuestion *question = [self.sectionsFetchedResultsController objectAtIndexPath:indexPath];     
    //[self show: animated:YES];
    NSLog(@"CheckListViewController::didSelectRowAtIndexPath - ended"); 
}

#pragma mark -
#pragma mark FetchedResultsController

- (NSFetchedResultsController *)sectionsFetchedResultsController {
    // Set up the fetched results controller if needed.
    NSLog(@"ChecklistViewController::sectionsFetchedResultsController - started");

    if (sectionsFetchedResultsController == nil) {

        NSLog(@"ChecklistViewController::fetchedResultsController - FETCHING new results");     

        NSManagedObjectContext *managedObjectContext = [**ContextManager sharedContext] managedObjectContext];    

        // Create the fetch request for the entity.
        NSFetchRequest *fetchRequest = [**NSFetchRequest alloc] init];

        NSEntityDescription *entity = [NSEntityDescription entityForName:@"InspectionQuestion" inManagedObjectContext:managedObjectContext];
        [fetchRequest setEntity:entity];

        NSSortDescriptor *sortDescriptor = [**NSSortDescriptor alloc] initWithKey:@"sectionId" ascending:YES];
        NSArray *sortDescriptors = [**NSArray alloc] initWithObjects:sortDescriptor, nil];
        [fetchRequest setSortDescriptors:sortDescriptors];


        NSFetchedResultsController *aFetchedResultsController = [**NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil 
           cacheName:nil
//                   cacheName:@"Root"
        ];

        //aFetchedResultsController.delegate = self;
        self.sectionsFetchedResultsController = aFetchedResultsController;
//        self.sectionsFetchedResultsController.delegate = self;

/* ARC
        [aFetchedResultsController release];
        [fetchRequest release];
        [sortDescriptor release];
        [sortDescriptors release];
*/ 
    }

    return sectionsFetchedResultsController;
}  


- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    if ( controller == self.sectionsFetchedResultsController ) {
        [self.sectionsTable.tableView beginUpdates];
    }
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
    UITableView *tableView;

    if ( controller == self.sectionsFetchedResultsController ) {
        tableView = self.sectionsTable.tableView;
    }    

    switch(type) {
        case NSFetchedResultsChangeInsert:
            NSLog(@"ChecklistViewController::didChangeObject - INSERT");
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            NSLog(@"ChecklistViewController::didChangeObject - DELETE");
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            NSLog(@"ChecklistViewController::didChangeObject - UPDATE");
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            NSLog(@"ChecklistViewController::didChangeObject - MOVE");
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.sectionsTable.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.sectionsTable.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    [self.sectionsTable.tableView endUpdates];
}


@end


谢谢

最佳参考


尝试将UITableViewController更改为UITableView


UITableView       *sectionsTable;


并将类型设为UIViewController a UITableViewController


@interface ChecklistViewController : UITableViewController <NSFetchedResultsControllerDelegate,
                                                    UITableViewDelegate,
                                                    UITableViewDataSource>

其它参考1


我发现了问题 - UITableViewController未正确添加到视图层次结构中


代替


- (void)viewDidLoad
{
    [super viewDidLoad];

    //Setup tableviews
    self.sectionsTable = [**UITableViewController alloc] init]; 
    self.sectionsTable.view = self.sectionsView;
    self.sectionsTable.tableView.dataSource = self;         
    self.sectionsTable.tableView.delegate = self;    


它应该是


- (void)viewDidLoad
{
    [super viewDidLoad];

    //Setup tableviews
    self.sectionsTable = [**UITableViewController alloc] init];     
    [self.sectionsView addSubview:self.sectionsTable.view];
    self.sectionsTable.tableView.dataSource = self;         
    self.sectionsTable.tableView.delegate = self;     


注意:仍然需要设置sectionsTable.view的框架。


现在正在调用tableview和FRC委托方法,并且tableview呈现。