2009-10-05 54 views
4

爲什麼在重新創建NSFetchedResultsControllerNSFetchRequest時,[NSFetchedResultsController performFetch:]會崩潰?爲什麼NSFetchedResultsController執行Fetch:使用等價的NSFetchRequest重新創建NSFetchedResultsController時崩潰?

我有一個應用程序具有線程(消息線程)的表視圖控制器。當你點擊一個線程時,它將加載另一個表視圖控制器,該控制器使用NSFetchedResultsController獲取該線程的所有消息並顯示它們。我使用NSFetchedResultsController,因爲我可以在後臺加載消息/刪除/添加新消息,而不必擔心顯示它們。

第二個表視圖控制器用於所有的線程,所以當我點擊回來然後點擊另一個線程我只是刪除當前NSFetchedResultsController併爲新線程設置一個新的。

下面是重現崩潰的步驟:

  1. 絲錐螺紋因此它顯示我的消息。
  2. 重新加載消息,所以NSFetchedResultsController被用來顯示新的消息。
  3. 回去吧。
  4. 點擊另一個線程。
  5. 回去吧。
  6. 點擊第一個線程。

在攻絲NSFetchedResultsController被創建時,它與第一個相同。 (相同的緩存和一切)。相反,像它的工作應該它給這個錯誤和崩潰:

Program received signal: 「EXC_BAD_ACCESS」.

NSFetchedResultsController被髮送消息已釋放對象。

這裏是堆棧跟蹤:

#0 0x95ffd688 in objc_msgSend 
#1 0x0060699b in -[NSFetchedResultsController(PrivateMethods) _computeSectionInfo:error:] 
#2 0x00601bf0 in -[NSFetchedResultsController performFetch:] 
#3 0x0001c170 in -[CMNewMessagesViewController loadMessagesViewControllerForThread:showProfile:] at CMNewMessagesViewController.m:331 

3是我的方法

在所有什麼想法?任何幫助將非常感激。


已解決!

這是我的錯。我使用的是從另一個鍵值派生的sectionNameKeyPath。只要NSFetchRequest按鍵值排序,就可以。問題在於它是動態生成的,因爲我不想浪費數據庫中的空間。我在NSManagedObject類中使用了一個由didTurnIntoFault清理的實例變量。

現在,我認爲實例變量必須已經創建,然後丟棄,然後在某些時候重新創建NSFetchedResultsController的排序磨合停頓。

這解釋了爲什麼沒有sectionNameKeyPath或委託解決了這個問題。

現在,我已經切換到CoreData對象中保存的鍵值,它似乎工作得很好。

回答

0

這是我的錯。我使用的是從另一個鍵值派生的sectionNameKeyPath。只要NSFetchRequest按鍵值排序,就可以。問題在於它是動態生成的,因爲我不想浪費數據庫中的空間。我在NSManagedObject類中使用了一個由didTurnIntoFault清理的實例變量。

現在,我認爲實例變量必須已經創建,然後丟棄,然後在某些時候重新創建NSFetchedResultsController的排序磨合停頓。

這解釋了爲什麼沒有sectionNameKeyPath或委託解決了這個問題。

現在,我已經切換到CoreData對象中保存的鍵值,它似乎工作得很好。

1

當調用performFetch時,我在系統堆棧中獲得了相同的EXC_BAD_ACCESS信號。緩存或其他任何變化都無濟於事。

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate]; 
    managedContext = [appDelegate managedObjectContext]; 

    NSError *error = nil; 
    NSFetchedResultsController *frC = self.fetchedResultsController; 
    if (![frC performFetch:&error]) { 
     /* */ 
    } 
} 

最近我發現了一個小片段添加。實際上,問題是我使用iOS內存管理(或者沒有使用過)的方式。

- (NSFetchedResultsController *)fetchedResultsController { 
    if (fetchedResultsController != nil) { 
     return fetchedResultsController; 
    } 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Asiakasrekisteri" inManagedObjectContext:managedContext]; [fetchRequest setEntity:entity]; 

    [fetchRequest setFetchBatchSize:200]; 

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"yritys" ascending:YES]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 

    [fetchRequest setSortDescriptors:sortDescriptors]; 

    NSFetchedResultsController *aFetchedResultsController = 
     [[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedContext sectionNameKeyPath:nil cacheName:nil] retain]; 

    aFetchedResultsController.delegate = self; 
    self.fetchedResultsController = aFetchedResultsController; 

    [aFetchedResultsController release]; 
    [fetchRequest release]; 
    [sortDescriptor release]; 
    [sortDescriptors release]; 
    return fetchedResultsController; 
} 

aFetchedResultsController確實有很短的獨立生活,但它performFetch之前釋放。 A 保留確實幫助和resultscontroller保持分配。

相關問題