2011-08-11 64 views
3

也许我不打算使用CoreData显示选定行的详细信息,但我无法弄清楚为什么会出现“BAD_ACCESS”错误。我搜索了一下,找不到我在找什么。核心数据DetailTableView BAD_ACCESS错误

基本上我使用CoreData来填充表视图的数据。它检索所有实体的所有标题属性。当用户点击一行时,我有一个详细视图,需要显示该实体的描述。我想我需要在我的DetailViewController中为新的NSFetchRequest创建一个新的NSManagedObjectContext和一个新的NSEntityDescription,然后使用NSPredicate来说“where title = [user selected 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数据库。

您还可以在my github page上下载我的项目。

+0

我发现了这个问题。当我不应该去的时候,我正在释放物体。 A 非常好苹果开发者论坛上的苹果员工告诉我,我不知道什么是内存管理,并给了我一个链接到标准800页Apple Dev内存管理文档的链接。 – Miles

+0

我在苹果开发者论坛上从不同的用户那里得到了更好的回应:“在这种情况下,违规是你打电话 - 在你不应该的情况下发布 - 如果你想让Xcode告诉你你做了一个干净的项目构建,然后使用“构建和分析”选项,如果一切正常,至少会有一个关于您在原始消息中发布的方法的蓝色图标消息。 我给了他点答案,并感谢他。 – Miles

回答

1

通常情况下,使用Core Data支持的Master-Detail界面,您不会获取Detail视图。

当您在Master tableview中选择一行时,您正在选择一个特定的托管对象实例。然后您将该托管对象实例传递给详细视图。没有必要重新获取您在tableview中选择的对象。

一个很好的例子就是联系人应用程序。 Master tableview将是Contact对象列表(显示名称)。当您选择一行时,Master tableview控制器将与选定行关联的特定Contact对象传递给Detail视图控制器,然后将该视图填充到Detail使用传递的Contact对象的属性中的数据进行查看。

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

但是,此代码中的直接错误是您要释放未创建的对象。在这一行:

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

...你是不是有initnewcreate方法创建一个NSArray的实例。相反,你只是接收一个自动发布的NSArray实例,该实例创建并由context NSManagedObjectContext实例返回。当你释放一个物体时,你并没有在这里创建:

[objects release]; 

......你会导致崩溃。

反之,你就在这里创建NSFetchRequest:

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

...因为你用init所以你必须以平衡搭配:

[request relwase]; 

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

+0

感谢TechZen - 很好的解释! – Miles