当我尝试将数据从Core Data加载到Table View控制器时,出现错误。我相信这是因为没有正确传递managedObject。
但我相信我是在对didFinishLaunchingWithOptions下的AppDelegate.m中的代码进行一些研究后这样做的。
错误
***由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:'+ entityForName:nil不是合法的NSManagedObjectContext参数,用于搜索实体名称'Club''
MLVAPPDelegate.h
#import <UIKit/UIKit.h>
@interface MLVAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@end
MLVAppDelegate.m
#import "MLVAppDelegate.h"
#import "MLVSyncEngine.h"
#import "Club.h"
#import "IronSet.h"
#import "MLVClubSelectionViewController.h"
@implementation MLVAppDelegate
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UITabBarController *tabController = (UITabBarController *)self.window.rootViewController;
UINavigationController *navigationController = (UINavigationController *)[[tabController viewControllers] objectAtIndex:0];
MLVClubSelectionViewController *controller = (MLVClubSelectionViewController *)[[navigationController viewControllers] objectAtIndex:0];
controller.managedObjectContext = self.managedObjectContext;
[[MLVSyncEngine sharedEngine] registerNSManagedObjectClassToSync:[Club class]];
[[MLVSyncEngine sharedEngine] registerNSManagedObjectClassToSync:[IronSet class]];
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[[MLVSyncEngine sharedEngine] startSync];
}
- (NSManagedObjectContext *)masterManagedObjectContext {
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_managedObjectContext performBlockAndWait:^{
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}];
}
return _managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"GolfCalculator" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"GolfCalculator.sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
#pragma mark - Application's Documents directory
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
@end
MLVClubSelectionViewController.h
#import <UIKit/UIKit.h>
@interface MLVClubSelectionViewController : UITableViewController
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@end
MLVClubSelectionViewController.m
#import "MLVClubSelectionViewController.h"
#import "Club.h"
#import "IronSet.h"
#import "MLVCoreDataController.h"
@interface MLVClubSelectionViewController ()
@end
@implementation MLVClubSelectionViewController
@synthesize managedObjectContext;
@synthesize fetchedResultsController = _fetchedResultsController;
- (void)viewDidLoad
{
[super viewDidLoad];
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
// Update to handle the error appropriately.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
self.title = @"Club Selection";
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
id sectionInfo =
[[_fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
Club *info = [_fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = info.fullTitle;
cell.detailTextLabel.text = [NSString stringWithFormat:@"%@, %@",
info.model, info.level];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Set up the cell...
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
#pragma mark - Fetched Results
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Club" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@"make" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext sectionNameKeyPath:nil
cacheName:@"Root"];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller is about to start sending change notifications, so prepare the table view for updates.
[self.tableView beginUpdates];
}
- (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:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray
arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray
arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )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];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[self.tableView endUpdates];
}
- (void)viewDidUnload {
self.fetchedResultsController = nil;
}
@end
答案 0 :(得分:1)
您已实施方法masterManagedObjectContext
,但您从未对其进行过调用。您将分配managedObjectContext
属性的值(因为所有对象属性将初始化为nil
),作为传递给控制器的上下文。
您可以执行以下操作之一:
masterManagedObjectContext
重命名为managedObjectContext
,这将提供managedObjectContext
访问者的延迟加载实现(意味着self.managedObjectContext
不应再评估为nil
)您也可以按如下方式实施managedObjectContext
:
- (NSManagedObjectContext *)managedObjectContext {
return [self masterManagedObjectContext];
}
从应用委托中删除managedObjectContext
属性,仅使用masterManagedObjectContext
方法。这还需要明确定义_managedObjectContext
实例变量。