【发布时间】:2011-05-01 00:54:33
【问题描述】:
我有两个显示 CoreData 对象的 tableview 控制器。一种是详细视图(带有句子),一种是概述(带有故事)。 选择一个故事 -> 查看句子。
看起来我过度释放了我的 managedObjectContext;我最初在 dealloc 中的两个 TableViewControllers 中都发布了它,并且每三次在两个控制器之间(故事 -> 句子 -> 故事 -> 句子 -> 故事 -> 崩溃)都会发生崩溃。 一些调试表明,在两个 TableViewController 的 ViewDidLoad 中的这段代码之后,我的 App Delegate 崩溃了:
if (managedObjectContext == nil)
{
managedObjectContext = [(StoryBotAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(@"After managedObjectContext: %@", managedObjectContext);
}
更多研究发现 this discussion 让我相信这是过度释放的 ManagedObjectContext 的情况:
第二个更平淡无奇的问题只是过度发布 NSManagedObject。 Instruments ObjectAlloc 工具应该可以提供帮助 你。
所以我删除了 [managedObjectContext release];从我在 TableViewController 中的 dealloc,现在我没有泄漏(根据 Instruments)并且没有崩溃。
看起来问题已经解决了,但问题是:
我可能完全忽略了这一点,只是隐藏了另一个问题。我如何才能找到过度发布或真正的问题?
如果我已经解决了这个问题,我想知道为什么它被修复了,为什么我不需要在第二个 TableViewController 中释放 MOC
MakeSentenceTableViewController.m
@implementation MakeSentenceTableViewController
@synthesize story, managedObjectContext;
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"My Story";
NSLog(@"Passed Story Object: %@", story);
if (managedObjectContext == nil)
{
NSLog(@"managedObjectContext == nil");
managedObjectContext = [(StoryBotAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(@"After managedObjectContext: %@", managedObjectContext);
}else{
NSLog(@"managedObjectContext != nil");
}
NSFetchRequest *request = [[NSFetchRequest alloc] init];
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]);
}
//snip...table view bits
- (void)dealloc {
[fetchedResultsController release];
//Why don't I have to release this?
//[managedObjectContext release];
[super dealloc];
}
【问题讨论】:
标签: iphone cocoa-touch core-data memory-leaks release-management