由于核心数据错误导致TableView崩溃/冻结 [英] TableView Crashing/Freezing Because Of Core Data Error

查看:71
本文介绍了由于核心数据错误导致TableView崩溃/冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户单击导航栏中的+按钮时,出现带有文本提示的UIAlert.然后,用户在提示符下输入一个字符串,这将产生一个新的UITableViewCell,名称为该字符串.

When the user clicks the + button in the navbar, a UIAlert with text prompt comes up. The user then enters a string into the prompt and it should result in a new UITableViewCell with the name as the string.

由于某种原因,当我进入该viewController的屏幕时,应用程序崩溃了.

For some reason the app is crashing when I get to the screen for this viewController.

它认为它与ViewDidLoad中的以下行有关:NSEntityDescription *entity = [NSEntityDescription entityForName:@"Routine" inManagedObjectContext:managedObjectContext];.

It think it is related to the following line in ViewDidLoad: NSEntityDescription *entity = [NSEntityDescription entityForName:@"Routine" inManagedObjectContext:managedObjectContext];.

控制台显示以下内容:Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Routine''

The console says the following: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Routine''

我认为我需要使用名称"而不是常规名称,但这也不起作用.

I think I need to use "name" instead of routine but that isn't working either.

这是我的核心数据模型:

Here is my Core Data Model:

这是我的代码:

#import "RoutineTableViewController.h"
#import "AlertPrompt.h"
#import "Routine.h"

@implementation RoutineTableViewController

@synthesize tableView;
@synthesize eventsArray;
@synthesize managedObjectContext;

    - (void)dealloc
    {
        [managedObjectContext release];
        [eventsArray release];
        [super dealloc];
    }

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

    #pragma mark - View lifecycle

    - (void)viewDidLoad
    {
        UIBarButtonItem * addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(showPrompt)];
        [self.navigationItem setLeftBarButtonItem:addButton];
        [addButton release];

        UIBarButtonItem *editButton = [[UIBarButtonItem alloc]initWithTitle:@"Edit" style:UIBarButtonItemStyleBordered target:self action:@selector(toggleEdit)];
        self.navigationItem.rightBarButtonItem = editButton;
        [editButton release];

        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Routine" inManagedObjectContext:managedObjectContext];
        [request setEntity:entity];

        NSError *error = nil;
        NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
        if (mutableFetchResults == nil) {
            // Handle the error.
        }

        [self setEventsArray:mutableFetchResults];
        [mutableFetchResults release];
        [request release];

        [super viewDidLoad];
    }

    -(void)toggleEdit
    {
        [self.tableView setEditing: !self.tableView.editing animated:YES];

        if (self.tableView.editing)
            [self.navigationItem.rightBarButtonItem setTitle:@"Done"];
        else
            [self.navigationItem.rightBarButtonItem setTitle:@"Edit"];
    }

    -(void)showPrompt
    {
        AlertPrompt *prompt = [AlertPrompt alloc];
        prompt = [prompt initWithTitle:@"Add Workout Day" message:@"\n \n Please enter title for workout day" delegate:self cancelButtonTitle:@"Cancel" okButtonTitle:@"Add"];

        [prompt show];
        [prompt release];
    }

    - (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
    {
        if (buttonIndex != [alertView cancelButtonIndex])
        {
            NSString *entered = [(AlertPrompt *)alertView enteredText];
            if(eventsArray && entered)
            {
                [eventsArray addObject:entered];
                [tableView reloadData];
            }
        }
    }

    -(void)addEvent
    {
        Routine *routine = (Routine *)[NSEntityDescription insertNewObjectForEntityForName:@"Routine" inManagedObjectContext:managedObjectContext];

        NSError *error = nil;
        if (![managedObjectContext save:&error]) {
            // Handle the error.
        }

        [eventsArray insertObject:routine atIndex:0];
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                              withRowAnimation:UITableViewRowAnimationFade];
        [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
    }

    - (void)viewDidUnload
    {
        self.eventsArray = nil;
        [super viewDidUnload];
    }

#pragma mark - Table view data source

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return 1;
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [eventsArray count];
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            //cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellEditingStyleDelete reuseIdentifier:CellIdentifier] autorelease];
        }
        cell.textLabel.text = [self.eventsArray objectAtIndex:indexPath.row];

        return cell;
    }
    // Override to support conditional editing of the table view.
    - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
    {
        // Return NO if you do not want the specified item to be editable.
        return YES;
    }

    -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
     {

         if (editingStyle == UITableViewCellEditingStyleDelete) {

             // Delete the managed object at the given index path.
             NSManagedObject *eventToDelete = [eventsArray objectAtIndex:indexPath.row];
             [managedObjectContext deleteObject:eventToDelete];

             // Update the array and table view.
             [eventsArray removeObjectAtIndex:indexPath.row];
             [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];

             // Commit the change.
             NSError *error = nil;
             if (![managedObjectContext save:&error]) {
                 // Handle the error.
             }
         }
     }    
    @end

推荐答案

我看不到您的ManagedObjectContext声明在何处并与现有数据模型挂钩.与之类似,您在哪里声明要从 persistentStoreCoordinator 访问它的"getter".尝试检查您的连接并在viewDidLoad上插入.并在此处检查文档步骤:

I'm not seeing where your ManagedObjectContext is declared and hooked into your existing data model. As in, where do you declare your "getter" for accessing it from the persistentStoreCoordinator. Try checking your connection and inserting on viewDidLoad. And check the documentation steps here:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdUsingMOM.html#//apple_ref/doc/uid/TP40005190-SW1

这是它与您的perstistantStoreCoordinator挂钩的一个示例

Here's an example of it hooking into your perstistantStoreCoordinator

- (NSManagedObjectContext *) managedObjectContext {

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

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
    managedObjectContext = [[NSManagedObjectContext alloc] init];
    [managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;

}

或者从您正在使用的教程中,您将在应用程序委托的 didFinishLaunching 方法中看到它:

Or from the tutorial you're using, you'll see it in the application delegate's didFinishLaunching method :

NSManagedObjectContext *context = [self managedObjectContext];
if (!context) {
    // Handle the error.
}
// Pass the managed object context to the view controller.
rootViewController.managedObjectContext = context;

编辑

查看代码后,您需要做两件事:

After reviewing your code, you need to do two things :

1)编辑您的AppDelegate以加载卷曲"模型,而不是临时"模型.那就是您的xdatamodel的名称.

1) edit your AppDelegate to load the "Curl" model, not the "Temp" model. That's the name of your xdatamodel.

2)您需要引用您的应用程序委托的上下文,而不是在本地创建.即

2) You need to reference your app delegate's context and NOT make one locally. I.e.

CurlAppDelegate *curlAppDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [curlAppDelegate managedObjectContext];

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Routine" inManagedObjectContext:context];
    [request setEntity:entity];

    NSError *error = nil;
    NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];
    if (mutableFetchResults == nil) {
        // Handle the error.
    }

这篇关于由于核心数据错误导致TableView崩溃/冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆