从UITableViewController将NSFetchedResultsController迁移到UIViewController

时间:2013-07-27 22:51:30

标签: iphone ios objective-c core-data nsfetchedresultscontroller

为了规避NSFetchedResultsController固有的一些问题,我决定将我的UITableViewController更改为UIViewController,只需添加一个tableView属性。我没有使用故事板,而是以编程方式制作所有内容。这样做的目的是让一个表视图从顶部在y轴上留下大约44 px的空白空间(所以我可以在那里放置一个通用标题)。基本上,我试图将tableview向下移动44 px。

问题是,我在fetchedResultsController上遇到断点错误。这是我的代码:

ViewController.h

@interface ToDoViewController : UIViewController <UITableViewDelegate, SettingsViewControllerDelegate, NSFetchedResultsControllerDelegate, UITableViewDataSource>
@property (nonatomic) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic) NSFetchedResultsController *fetchedResultsController;
@end

ViewController.m

@implementation ToDoViewController
@synthesize managedObjectContext;
@synthesize fetchedResultsController = _fetchedResultsController;
@synthesize tableView = _tableView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        UINavigationItem *i = [self navigationItem];
        [i setTitle:@"Task List"];
_tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 44, 320, 548) style:UITableViewStyleGrouped];
        [self.view addSubview:self.tableView];
        self.tableView = self.fetchedResultsController.delegate;

    }
    return self;


-(void) viewDidLoad{
    [super viewDidLoad];

   NSError *error;
    if (![[self fetchedResultsController] performFetch:&error]){
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);
    } 

    [self.tableView setDelegate:self];
    [self.tableView setDataSource:self];

    [self.tableView setBackgroundView:nil];
    [self.tableView setBackgroundColor:baseColor];
    [self.view setBackgroundColor:baseColor];

- (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
                                   entityForName:@"Tasks" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *isCompleted = [[NSSortDescriptor alloc]initWithKey:@"sectionString" ascending:NO];
    NSSortDescriptor *sort = [[NSSortDescriptor alloc]
                              initWithKey:@"dateCreated" ascending:YES];
    [fetchRequest setSortDescriptors:@[isCompleted, sort]];
    [fetchRequest setFetchBatchSize:20];

    NSFetchedResultsController *theFetchedResultsController =
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                        managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"sectionString"
                                                   cacheName:nil];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;

}

问题是表视图没有填充nsfetchedresultscontroller应该提取的项目。我不知道为什么会这样......也许是因为tableview不是代表或什么?

2 个答案:

答案 0 :(得分:0)

NSFetchedResultsControllerDelegate用于监控核心数据实体的更改,因此您不需要

    self.tableView = self.fetchedResultsController.delegate;

您需要使用NSFetchedResultsController实现UITableViewDelegate方法。主要

- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
    id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController.sections objectAtIndex:section];
    return sectionInfo.numberOfObjects;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
    return cell;
}

注意:创建NSFetchedResultsController后,还必须调用performFetch:

通过使用Master-Detail模板并选中“Use Core Data”,您可以看到实现所有这些功能的一个很好的示例。

答案 1 :(得分:0)

对我来说,来自UITableViewController转到包含UITableView的UIViewController,我必须执行以下操作才能使NSFetchedResultsController工作:

  1. 使视图控制器处理UITableView和UITableViewDataSource的委托方法:

    @interface UIViewControllerName:UIViewController&lt; UITableViewDelegate,NSFetchedResultsControllerDelegate,UITableViewDataSource&gt;

  2. 设置UITableView的委托和数据源(在我的情况下,我使用故事板中的插件将其称为tableView)为self(在我的情况下为viewDidLoad)

    [super viewDidLoad];
    
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    
    appDelegate = [[UIApplication sharedApplication] delegate];
    self.managedObjectContext = [appDelegate managedObjectContext];
    
    NSError *error;
    if (![self.fetchedResultsController performFetch:&error]) {
        // handle error
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1); // fail
    }