我正在关注核心数据教程以及如何使用NSFetchResultController,但我无法呈现数据而我无法找到问题。
以下是我的表格视图中可能出现问题的一些代码:
这是我的PatientTableViewController.h:
#import <UIKit/UIKit.h>
#import "Petient.h"
@interface PetientTableViewController : UITableViewController <NSFetchedResultsControllerDelegate>
@property (nonatomic, strong) Petient *petient;
@end
PatientTableViewController.m:
#import "PetientTableViewController.h"
#import "AppDelegate.h"
#import "AddPetientViewController.h"
@interface PetientTableViewController ()
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) NSFetchedResultsController *fetchResultController;
@end
@implementation PetientTableViewController
-(NSManagedObjectContext *)managedObjectContext
{
return [(AppDelegate *)[[UIApplication sharedApplication]delegate] managedObjectContext];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSError *error = nil;
if (![self.fetchResultController performFetch:&error]) {
NSLog(@"Error! %@", error);
abort();
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self.fetchResultController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchResultController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
// Configure the cell...
Petient *petient = [self.fetchResultController objectAtIndexPath:indexPath];
cell.textLabel.text = petient.patientLastName;
cell.detailTextLabel.text = petient.patientFirstName;
return cell;
}
#pragma mark - Fetched Result Controller Section
- (NSFetchedResultsController *)fetchResultController
{
if (_fetchResultController != nil) {
return _fetchResultController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context = [self managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Petient" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"patientLastName" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
fetchRequest.sortDescriptors = sortDescriptors;
_fetchResultController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
_fetchResultController.delegate = self;
return _fetchResultController;
}
#pragma mark - Fetched Result Controller Delegates
-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}
-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;
switch (type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate: {
Petient *changePatient = [self.fetchResultController objectAtIndexPath:indexPath];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.text = changePatient.patientLastName;
}
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
default:
break;
}
}
-(void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch (type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
default:
break;
}
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"addPatient"]) {
UINavigationController *nav = [segue destinationViewController];
AddPetientViewController *destination = (AddPetientViewController *)[nav topViewController];
Petient *addPatient = [NSEntityDescription insertNewObjectForEntityForName:@"Petient" inManagedObjectContext:self.managedObjectContext];
destination.addPatient = addPatient;
}
}
@end
这是我的模型类Petient.h:
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Prescription;
@interface Petient : NSManagedObject
@property (nonatomic, retain) NSString * patientLastName;
@property (nonatomic, retain) NSString * patientFirstName;
@property (nonatomic, retain) NSSet *prescriptions;
@end
@interface Petient (CoreDataGeneratedAccessors)
- (void)addPrescriptionsObject:(Prescription *)value;
- (void)removePrescriptionsObject:(Prescription *)value;
- (void)addPrescriptions:(NSSet *)values;
- (void)removePrescriptions:(NSSet *)values;
@end
这是我的AddPatientViewController.h:
#import <UIKit/UIKit.h>
#import "CoreViewController.h"
#import "Petient.h"
@interface AddPetientViewController : CoreViewController
@property (weak, nonatomic) IBOutlet UITextField *patientFirstName;
@property (weak, nonatomic) IBOutlet UITextField *patientLastName;
@property (nonatomic, strong) Petient *addPatient;
// Actions
- (IBAction)cancel:(UIBarButtonItem *)sender;
- (IBAction)save:(UIBarButtonItem *)sender;
@end
这是我的AddPatientViewController.m:
#import "AddPetientViewController.h"
@interface AddPetientViewController ()
@end
@implementation AddPetientViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)cancel:(UIBarButtonItem *)sender
{
[super cancelAndDisMiss];
}
- (IBAction)save:(UIBarButtonItem *)sender
{
self.addPatient.patientFirstName = _addPatient.patientFirstName;
self.addPatient.patientLastName = _addPatient.patientLastName;
[super saveAndDismiss];
}
@end
答案 0 :(得分:1)
您需要实际实现NSFetchedResultsControllerDelegate的委托方法,以便告诉表何时加载内容。例如,当调用-controllerWillChangeContent时,可以在表上调用 -reloadData :
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView reloadData];
}
答案 1 :(得分:1)
在- (IBAction)save:(UIBarButtonItem *)sender
中,你得到了:
self.addPatient.patientFirstName = _addPatient.patientFirstName;
self.addPatient.patientLastName = _addPatient.patientLastName;
这不应该来自UITextField
s?
self.addPatient.patientFirstName = self.patientFirstName.text;
self.addPatient.patientLastName = self.patientLastName.text;