无法在 dealloc 中释放 NSFetchedResultsController

发布于 2024-09-29 09:39:34 字数 2933 浏览 5 评论 0原文

我有两个 UITableViewController,其 ui 流程相当简单。当您在第一个 UITableViewController 中选择一个项目时,一个 UITableViewController 会加载另一个 UITableViewController。


(UITableViewController) 故事列表 ->选择一个故事 -> (UITableViewController) 句子列表


在第二个 UITableViewController (MakeSentenceDetailViewController) 中,我无法释放 NSFetchedResultsController 而不导致错误(显示为“僵尸”设置为打开):

-[NSFetchRequest release]:消息发送到已释放的实例 0x5b370f0

NSFetchedResultsController 的保留计数保持为 1,但当我尝试在 dealloc 中释放它时,我遇到了崩溃。

两个表视图中的代码(尤其是与 NSFetchedResultsController 相关的代码)是相同的,但在 MakeSentenceDetailViewController 中,我无法在崩溃时释放此 NSFetchedResults Controller - 这给了我一个泄漏。

如何安全地释放我的 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];
 }

I have two UITableViewControllers with a fairly simple ui flow. One UITableViewController loads another UITableViewController when you select an item in the first UITableViewController.


(UITableViewController) List of Stories -> Select a Story -> (UITableViewController) List of Sentences


In the second UITableViewController (MakeSentenceDetailViewController) I can't release my NSFetchedResultsController without causing an error (shown with Zombies set to on):

-[NSFetchRequest release]: message sent to deallocated instance 0x5b370f0

The retain count of the NSFetchedResultsController stays at 1 but when I try to release it in dealloc I get a crash.

The code, especially in regards to the NSFetchedResultsController is the same in both tableviews, but in the MakeSentenceDetailViewController I can't release this NSFetchedResults Controller with a crash - giving me a leak.

How can I safely release my NSFetchedResultsController? Why does it work fine in the parent (first) tableviewcontroller - but not in the second?

I can provide code for the first UITableViewController but in regards to NSFetchedResultsController it's declared and used in much the same way.

MakeSentenceTableViewController.h:

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

MakeSentenceTableViewController.m (relevant code with 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];
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

灼疼热情 2024-10-06 09:39:35
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
// ...snip...
[request release];

您正在释放一个已放弃所有权的对象(使用 -autorelease)。在另一个版本中您不会收到错误,因为 NSFetchedResultsController 也保留了获取请求;因此,当控制器释放对获取请求的最后一个引用时,控制器才是真正导致崩溃的控制器。

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

You're releasing an object that you've relinquished ownership of (with -autorelease). You don't get an error at the point of the other release because the NSFetchedResultsController is also retaining the fetch request; thus the controller is the one actually causing the crash when it releases the last reference to the fetch request.

暖心男生 2024-10-06 09:39:35

你过度释放了 NSFetchRequest

你在这里自动释放它:

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

然后稍后再次释放它:

  [request release];

然后当你释放 fetchedResultsController 时,它会尝试再次释放相同的请求。

You are over-releasing the NSFetchRequest

You autorelease it here:

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

then release it again later:

  [request release];

then later when you release the fetchedResultsController, it tries to release that same request again.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文