为什么我不必在第二个 TableViewController 中释放 ManagedObjectContext

2024-02-10

我有两个显示 CoreData 对象的表视图控制器。一种是详细视图(带句子),一种是概述(带故事)。 选择一个故事 -> 查看句子。

看来我过度释放了管理对象上下文;我最初在 dealloc 的两个 TableViewController 中发布了它,并且每三次在两个控制器之间切换时都会发生崩溃(故事 -> 句子 -> 故事 -> 句子 -> 故事 -> 崩溃)。 一些调试显示,在两个 TableViewController 的 ViewDidLoad 中的此代码之后,我的应用程序委托崩溃了:

 if (managedObjectContext == nil) 
{ 
    managedObjectContext = [(StoryBotAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
    NSLog(@"After managedObjectContext: %@",  managedObjectContext);
}

更多研究发现这次讨论 http://www.cocoabuilder.com/archive/cocoa/242639-core-data-crash-on-moc-release.html这让我相信这是一个过度释放的 ManagedObjectContext 的情况:

第二个更平淡的问题只是过度发布 NSManagedObject。 Instruments ObjectAlloc 工具应该能够提供帮助 你。

所以我删除了 [managementObjectContext 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];
}

因为你没有保留它。即使视图控制器中的“MOC”属性是(保留),您也不会调用设置器,而只是直接设置引用。如果你想保留和释放它,你必须调用self. ManagedObjectContext = ...相反(注意点),这相当于[自行设置 ManagedObjectContext:...]只有这样你才能在 dealloc 中安全地释放它。实际上,由于“MOC”由应用程序委托拥有和管理,我什至懒得保留它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我不必在第二个 TableViewController 中释放 ManagedObjectContext 的相关文章

随机推荐