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,它会尝试再次发布相同的请求。

相关问题