ARC ViewController被取消分配

时间:2014-01-29 18:08:13

标签: ios automatic-ref-counting

我有一个显示按钮的视图控制器。单击按钮时,需要调用相应的选择器。但是,使用ARC,应用程序崩溃时出现EXC_BAD_ACCESS消息。

-(IBAction)reseauPushed:(id)sender{
  self.reseauVC = [[ReseauVCIpad alloc]initWithNibName:@"ReseauVCIpad" bundle:nil];
  [self.viewCenter addSubview:self.reseauVC.view];
}

  @property (strong, nonatomic) ReseauVCIpad *reseauVC;

和崩溃日志:

 -[ReseauVCIpad performSelector:withObject:withObject:]: message sent to deallocated instance

我使用 ARC 。 按钮操作:

-(IBAction)helloPushed:(id)sender{
   NSLog("hello);
}

2 个答案:

答案 0 :(得分:1)

这个ReseauVCIpad视图控制器显然已经取消分配了一些方法。您不小心将self.reseauVC设置为nil某处,或者更可能的是,父视图控制器本身会以某种方式被取消分配。您是否有可能为前面的任何一个视图控制器执行此addSubview技术?如果没有,你是如何实例化根视图控制器的?

要诊断问题所在,我建议您将dealloc方法添加到所有各种视图控制器中,以便确认是否有任何过早释放的方法。 (设置断点或放入NSLog语句。)我打赌你看到ReseauVCIpad的父级被解除分配,这反过来又允许ReseauVCIpad本身被解除分配


顺便说一句,正如其他人所指出的,这个问题的典型答案是确保你正在进行适当的收容调用(如下所示),或者如果这个子视图控制器占用整个屏幕,你应该只是推动它或模态呈现它。显然,您对strong有一个ReseauVCIpad引用,因此缺少包含调用并不是ReseauVCIpad本身问题的根源(尽管我不知道您是否正在执行此操作{{} 1}}使用一个或多个addSubview的父视图控制器进行包含调用的技巧。

但是你仍然应该进行这些包容调用(或进行正确的模态/推送转换),以确保您的视图控制器层次结构与视图层次结构保持同步(请参阅WWDC 2011视频Implementing UIViewController Containment讨论为什么这很重要)。适当的控制要求添加一个带有自己的控制器的子视图,至少如下:

ReseauVCIpad

有关更详细的说明,请参阅上面引用的视频,或参阅适用于iOS的View Controller编程指南的Creating Custom Container View Controllers部分。

当你想删除它时,你也应该在那里进行适当的收容调用:

- (IBAction)reseauPushed:(id)sender
{
    self.reseauVC = [[ReseauVCIpad alloc]initWithNibName:@"ReseauVCIpad" bundle:nil];
    [self addChildViewController:self.reseauVC];
    [self.viewCenter addSubview:self.reseauVC.view];
    [self.reseauVC didMoveToParentViewController:self];
}

这通常解决了这个问题(子视图控制器被解除分配)。它不会解决您的- (void)removeReseau { [self.reseauVC willMoveToParentViewController:nil]; [self.reseauVC.view removeFromSuperview]; [self.reseauVC removeFromParentViewController]; self.reseau = nil; } 问题(因为您已经有了强引用),但是(a)无论您在哪里使用视图控制器进行reseauVC,都应该这样做; (b)如果你在其他地方做addSubview而没有强有力的参考,我会告诉你模式。

答案 1 :(得分:0)

有几件事。除非设置父/子视图控制器关系,否则不应将一个视图控制器的内容视图添加到另一个视图控制器。这是在iOS 5中添加的,并在iOS 6中进行了扩展(并且可能在iOS 7中进一步扩展...)查看addChildViewController:,removeFromParentViewController,isMovingToParentViewController和didMoveToParentViewController等方法:

设置父/子视图控制器关系的最简单方法是使用故事板(需要iOS 5)和嵌入segue。 (我认为这是在iOS 6中添加的)。它负责为您设置父/子视图控制器关系的所有内务处理。

你的第二个视图控制器被保存为一个强大的属性,所以我不清楚为什么它被解除分配。我也不清楚对performSelector的调用:withObject:withObject:来自哪里。什么源代码行崩溃,你在代码中使用performSelector:withObject:withObject:?