CoreData DetailTableView BAD_ACCESS 错误

发布于 2024-11-29 02:16:49 字数 1819 浏览 2 评论 0原文

也许我不会使用 CoreData 显示所选行的详细信息,但我无法弄清楚为什么会收到“BAD_ACCESS”错误。我用谷歌搜索了一下,找不到我要找的东西。

基本上我使用 CoreData 来填充表视图的数据。它检索所有实体的所有标题属性。当用户单击一行时,我有一个需要显示该实体的描述的详细视图。我想我需要在 DetailViewController 中为新的 NSFetchRequest 创建一个新的 NSManagedObjectContext 和一个新的 NSEntityDescription,然后使用 NSPredicate 来表示“其中 title = [用户选择的标题]”。当我选择一行时出现错误。查看代码:

- (void)viewDidLoad
{
    // Do any additional setup after loading the view from its nib.

    // Get the objects from Core Data database
    Caregiver_Activity_GuideAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSEntityDescription *entityDescription = [NSEntityDescription
                                              entityForName:@"Definition"
                                              inManagedObjectContext:context];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDescription];

    NSPredicate *pred = [NSPredicate predicateWithFormat:@"(title = %@)", self.title];
    [request setPredicate:pred];

    NSError *error;
    NSArray *objects = [context executeFetchRequest:request error:&error];
    if (objects == nil) {
        NSLog(@"There was an error!");
        // Do whatever error handling is appropriate
    }

    for (NSManagedObject *oneObject in objects) {
        [definitionDescriptionTextView setText:[oneObject valueForKey:@"desc"]];
    }

    [objects release];
    [request release];

    [super viewDidLoad];
}

我注释掉该代码并且一切正常。但是当我尝试使用断点进行调试时,没有任何结果。所以我更困惑了。

我知道 CoreData 对于我正在做的事情来说可能有点过分了,但这对我来说是一个学习应用程序。

编辑:我没有包括我正在使用预先填充实体的 sqlite 数据库。

您还可以在我的 github 页面上下载我的项目。

Maybe I'm not going about showing a detail for a selected row using CoreData, but I can't figure out why I'm getting a "BAD_ACCESS" error. I've googled around and can't find what I'm looking for.

Basically I use CoreData to populate the data for a Table View. It retrieves all of the title attributes for all of the entities. When the user clicks on a row, I have a Detail View that needs to show the description for that entity. I think I need to make a new NSManagedObjectContext and a new NSEntityDescription for a new NSFetchRequest in my DetailViewController and then use a NSPredicate to say "where title = [user selected title]". I get an error when I select a row. See code:

- (void)viewDidLoad
{
    // Do any additional setup after loading the view from its nib.

    // Get the objects from Core Data database
    Caregiver_Activity_GuideAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSEntityDescription *entityDescription = [NSEntityDescription
                                              entityForName:@"Definition"
                                              inManagedObjectContext:context];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDescription];

    NSPredicate *pred = [NSPredicate predicateWithFormat:@"(title = %@)", self.title];
    [request setPredicate:pred];

    NSError *error;
    NSArray *objects = [context executeFetchRequest:request error:&error];
    if (objects == nil) {
        NSLog(@"There was an error!");
        // Do whatever error handling is appropriate
    }

    for (NSManagedObject *oneObject in objects) {
        [definitionDescriptionTextView setText:[oneObject valueForKey:@"desc"]];
    }

    [objects release];
    [request release];

    [super viewDidLoad];
}

I comment out that code and everything works. But when I try to debug with breakpoints, nothing catches. So I'm more confused.

I know CoreData is probably overkill for what I'm doing but this is a learning app for me.

EDIT: I didn't include that I'm using a sqlite database that is pre-populated with the entities.

You can also download my project on my github page.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一枫情书 2024-12-06 02:16:49

通常,使用核心数据支持的主从接口,您不会获取详细信息视图。

当您在主表视图中选择一行时,您正在选择一个特定的托管对象实例。然后,您将该托管对象实例传递到详细视图。无需重新获取您在表视图中选择的对象。

通讯录应用程序就是一个很好的例子。主表视图将是联系人对象的列表(显示名称)。当您选择一行时,主表视图控制器将获取与所选行关联的特定联系人对象,然后将其传递到详细信息视图控制器,然后由详细信息视图控制器填充详细信息使用从传递的 Contact 对象的属性中获取的数据进行视图。

因此,发生错误的整个代码块是不必要的。

然而,这段代码中的直接错误是您正在释放一个不是您创建的对象。在这一行中:

 NSArray *objects = [context executeFetchRequest:request error:&error];

...您没有使用 initnewcreate 方法创建 NSArray 实例。相反,您只是接收由 context NSManagedObjectContext 实例创建并返回的自动释放的 NSArray 实例。当您释放一个不是您在此处创建的对象时:

 [objects release];

...您会导致崩溃。

相反,您确实在此处创建了一个 NSFetchRequest:

 NSFetchRequest *request = [[NSFetchRequest alloc] init];

...因为您使用了 init,所以您必须通过以下方式进行平衡:

[request relwase];

顺便说一句,这种类型的代码不应放入 viewDidLoad 中> 因为仅当第一次从磁盘上的 nib 文件读取视图时才会调用该方法。这只能保证发生一次,因为当用户切换到另一个视图时,视图可能保留在内存中。相反,请将每次视图出现时都需要运行的代码放在 viewWillAppear 中。

Normally, with a Core Data backed Master-Detail interface, you don't fetch for the Detail view.

When you select a row in the Master tableview, you are selecting a particular managed object instance. You then pass that managed object instance to the detail view. There is no need to refetch the object that you selected in the tableview.

A good example of this would be the Contacts app. The Master tableview would be a list of Contact objects (displaying the name.) When you select a row, the Master tableview controller takes the specific Contact object associated with the selected row and then passes it to the Detail view controller which then populates the Detail view using data taking from the properties of the passed Contact object.

So, that entire code block where the error occurs is unnecessary.

However, the immediate error in this code is that you are releasing an object you didn't create. In this line:

 NSArray *objects = [context executeFetchRequest:request error:&error];

... you are not creating a NSArray instance with a init, new or create method. Instead, you are merely receiving an autoreleased NSArray instance created and returned by the context NSManagedObjectContext instance. When you release an object you did not create here:

 [objects release];

... you cause the crash.

Conversely, you do create a NSFetchRequest here:

 NSFetchRequest *request = [[NSFetchRequest alloc] init];

... because you used init so you do have to balance that with:

[request relwase];

BTW, this type of code should not be put in viewDidLoad as the method is only called when the view is read in the first time from the nib file on disk. That is only guaranteed to happen once as the view may remain in memory when the user switches to another view. Instead, put code that needs to run each time the view appears in viewWillAppear.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文