2011-05-15 46 views
4

我有一个视图控制器,我试图推入导航堆栈。我用局部变量创建控制器,设置它,然后将其分配给一个属性。然后,如果我释放变量,我会得到EXE_BAD_ACCESS。如果我保留(或自动释放)它会泄漏。如果我释放,我得到不好的访问,如果我保留,我泄漏

CustomTVC* controller = [[CustomTVC alloc]initWithStyle:UITableViewStyleGrouped]; 
controller.managedObjectContext = self.managedObjectContext; 

self.tableViewControllerIvar = controller; 

[self.navigationController pushViewController:self.tableViewControllerIvar animated:YES]; 
//[controller autorelease]; or [controller release]; or nothing 

这里是如果我释放

  1. 上面的代码是从导航栏按下添加按钮发射发生什么。
  2. 视图被推送,一切都很好。在新视图中,我可以一遍又一遍地推送更多视图,没有问题...除非
  3. 我回到导航堆栈的根视图。 (这是上述代码的来源)。
  4. 现在,如果我再次钻取到第二个视图,然后尝试推入另一个它崩溃。

编辑:我有一种感觉,当我将第三个控制器推入堆栈时出现了问题。通过推送,它将一个新对象插入托管对象上下文中,这会导致fetchedresultscontroller更新tableview。在那里可能有一个破碎的指针。我会玩它并发布结果。 -

编辑:5/16

在日志中收到此错误消息

* - [CustomTVC controllerWillChangeContent:]:消息发送到释放实例0x187270

这只发生在我将CustomTVC弹出堆栈(回到导航根视图控制器)后,我可以推送并保存所有I只要我不弹出CustomTVC即可。

+1

你应该能够发布一个你推到NVC栈的VC。但是你的代码显示你发布了变量'controller',但是在推送变量'VCTVC'之后?如果你推动'控制器'呢? – samvermette 2011-05-15 02:08:25

+1

请为'tableViewControllerIvar'显示'@ property'声明。 – 2011-05-15 03:32:11

+0

@property(nonatomic,retain)CustomTVC * tableViewControllerIvar; – 2011-05-15 04:21:50

回答

2

修复它。必须将获取的结果控制器委托设置为无viewDidLoad。

- (void)dealloc 
{ 
    self.fetchedResultsController.delegate = nil; 
    [_fetchedResultsController release]; 
    [_managedObjectContext release]; 
    [super dealloc]; 
} 

似乎是罪魁祸首(根据僵尸工具):

[NSFetchedResultsController(私有方法)_managedObjectContextDidChange:]

编辑(S):最后走上找出如何时把代码放在这里正确(我很懒)

+0

所以我猜这是一个很好的做法,设置代表为零以防止这种情况? – 2011-05-18 02:38:21

+0

根据[NSFetchedResultsController参考页面](http://tinyurl.com/69m8lbp),NSFetchedResultsController的delegate是'assign'属性,所以不要将它设置为nil不应该导致泄漏。你是否重新声明它保留?通常的做法是[对象不应保留其代表](http://tinyurl.com/6hput4n)以避免保留周期。 – Caleb 2011-05-18 04:10:17

+0

是的,将代表设置为'dealloc'上的'nil'总是个好主意。你永远不知道是否有人仍然保留具有委托属性的对象(即使你确实知道,你将来可能会改变它,并会忘记它可能会导致麻烦)。 – DarkDust 2011-05-19 08:28:17

0

autorelease应该完成工作。当您分配tableViewControllerIvar时,您可以拨打[controller autorelease]。这应该照顾到这一点。

CustomTVC* controller = [[CustomTVC alloc]initWithStyle:UITableViewStyleGrouped]; 
controller.managedObjectContext = self.managedObjectContext; 

self.tableViewControllerIvar = [controller autorelease]; 

[self.navigationController pushViewController:self.VCTVC animated:YES]; 

如果您仍然获得EXE_BAD_ACCESS,那么其他事情必须进行。您是否绝对确认过,此代码在多次运行时会导致访问不良?

+0

我有一种感觉,当我将第三个控制器推入堆栈时出现问题。通过推送,它将一个新对象插入托管对象上下文中,这会导致fetchedresultscontroller更新tableview。在那里可能有一个破碎的指针。我会玩它并发布结果。 – 2011-05-15 22:19:27

-1

你到tableViewControllerIvar

分配控制器
self.tableViewControllerIvar = controller; 

,你是释放控制器,所以你需要保留它在上面一行

self.tableViewControllerIvar = [controller retain]; 

,当你与你的“tableViewControllerIvar”完成那么只是释放它,你不应该得到任何泄漏

+1

设置属性与设置指针的值不同。这是调用一个方法,该方法应该适当地处理属性声明的保留计数。像你的第二行代码几乎总是错的;要么保留导致泄漏,或tableViewControllerIvar声明是错误的。 – smorgan 2011-05-15 04:23:29

+1

嘿,我们不知道Lone是否保留了财产...... – iOSDeveloperz 2011-05-15 04:38:26

+1

就像我说过的那样,这是错误的解决方法。如果该财产不是保留财产,那么正确的解决方法就是使其成为一个,而不是拥有声称不被保留但实际上“拥有”保留计数的财产。 – smorgan 2011-05-15 13:07:44

相关问题