2011-08-11 63 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