0

我有兩個UITableViewControllers與相當簡單的用戶界面流。當你在第一個UITableViewController中選擇一個項目時,一個UITableViewController加載另一個UITableViewController。不能釋放NSFetchedResultsController在dealloc


故事

(的UITableViewController)列表 - >選擇的故事 - 句子


在第二的UITableViewController(MakeSentenceDetailViewController)的>(的UITableViewController)名單我不能沒有引起釋放我NSFetchedResultsController錯誤(用殭屍設爲ON):

- [NSFetchRequest釋放]:消息發送到釋放的實例0x5b370f0

NSFetchedResultsController的保留計數保持在1,但是當我嘗試在dealloc中釋放它時,我得到一個崩潰。

代碼,特別是關於NSFetchedResultsController的代碼在兩個tableviews中都是一樣的,但是在MakeSentenceDetailViewController中我不能釋放這個帶有崩潰的NSFetchedResults控制器 - 給我一個泄漏。

如何安全地釋放我的NSFetchedResultsController?爲什麼它在父級(第一個)tableviewcontroller中工作正常 - 但不在第二級?

我可以爲第一個UITableViewController提供代碼,但對於NSFetchedResultsController,它的聲明和使用方式大致相同。

MakeSentenceTableViewController.h:

@interface MakeSentenceTableViewController : UITableViewController { 
NSManagedObjectContext *managedObjectContext; 
NSFetchedResultsController *fetchedResultsController; 
} 
@property (nonatomic, retain) Story *story; 
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; 
@end 

MakeSentenceTableViewController.m(與NSFetchedResultsController相關的代碼):

- (void)viewDidLoad { 
[super viewDidLoad]; 
if (managedObjectContext == nil) 
{ 
managedObjectContext = [(MyAppAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
NSLog(@"After managedObjectContext: %@", managedObjectContext); 
} 
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Sentence" inManagedObjectContext:managedObjectContext]; 
    [request setEntity:entity]; 
    //sorting stuff: 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"order" ascending: YES]; 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil]; 
    [request setSortDescriptors:sortDescriptors]; 
    //[request setFetchBatchSize:FETCH_BATCH_SIZE]; 
    [sortDescriptors release]; 
    [sortDescriptor release]; 
    fetchedResultsController = [[NSFetchedResultsController alloc] 
    initWithFetchRequest:request managedObjectContext:managedObjectContext 
    sectionNameKeyPath:nil cacheName:nil]; 
    [request release]; 
    NSError *error; 
    [fetchedResultsController performFetch:&error]; 
    NSLog(@"FetchedResultsController: %@", fetchedResultsController); 
    NSLog(@"fetchedResultsController RetainCount at viewDidLoad: %d", [fetchedResultsController retainCount]); 
} 

- (void)dealloc { 

    //Gotta figure out why I can't release this: 
    [fetchedResultsController release]; //Crash! Burn! 
    NSLog(@"fetchedResultsController RetainCount at dealloc: %d", [fetchedResultsController retainCount]); 
    [managedObjectContext release]; 
    [super dealloc]; 
} 

回答

0
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
// ...snip... 
[request release]; 

你釋放你已經放棄了所有權的對象( -autorelease)。您不會在其他發行版發生錯誤,因爲NSFetchedResultsController也保留了獲取請求;因此控制器是釋放對獲取請求的最後一個引用時實際導致崩潰的控制器。

+0

Thankyou - 修復問題,但它也創建(或顯示)另一個。現在我每進入MakeSentenceViewController(使用導航控制器在TableViewControllers之間切換),每隔三次(如發條),我會在這行代碼上崩潰:managedObjectContext = [(MyAppAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];你能看到任何明顯的連接?這超出了這個問題的範圍。 – glenstorey 2010-10-25 20:10:25

+0

取決於它是如何崩潰。 – 2010-10-26 05:06:06

+0

好的,我會在接下來的一週左右做一些額外的調試 - 如果我找到了,在這裏發佈解決方案,如果我不能,我會創建一個新的問題。感謝您的時間。 – glenstorey 2010-10-26 05:36:50

0

您是過度釋放NSFetchRequest

你自動釋放在這裏:

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

然後以後再釋放:

[request release]; 

再後來,當你鬆開fetchedResultsController,它會嘗試再次發佈相同的請求。

相關問題