Ios UIViewController视图错误

Ios UIViewController视图错误,ios,uiviewcontroller,Ios,Uiviewcontroller,我有一个UIB视图控制器,里面有一个关闭按钮 -(IBAction) close:(id) sender 从一个viewcontroller,我展示了如下的ViewB控制器 [self presentViewController:B animated:YES completion:NULL]; 然后一切都好了,我可以按B里面的关闭按钮 然而,如果我这样做 B* bcontrol=[[B alloc] init]; [self.view addsubview

我有一个UIB视图控制器,里面有一个关闭按钮

        -(IBAction) close:(id) sender 
从一个viewcontroller,我展示了如下的ViewB控制器

  [self presentViewController:B animated:YES completion:NULL];
然后一切都好了,我可以按B里面的关闭按钮

然而,如果我这样做

   B* bcontrol=[[B alloc] init];
   [self.view addsubview bcontrol.view];
这样,如果我按下关闭按钮,就会产生EXEC\u BAD\u访问错误


为什么呢?有什么想法吗?

我想你在用ARC

您将bcontrol创建为一个局部变量,并且不保留对它的引用,因此当您去掉它的视图时,ARC会释放它。然后,您的按钮尝试在解除分配的对象中触发一个操作…其余的您都知道


将B设为强属性,以便在需要它的视图时,它仍然存在。

您不为
close
方法提供代码。
close
方法代码必须更改,以符合您转换到此新视图的方式。如果您通过
presentViewController
查看控制器B,您可能会返回到一个via:

- (IBAction)close:(id)sender
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

你考虑如果通过

进入B控制器
B* bcontrol=[[B alloc] init];
[self.view addsubview bcontrol.view];
显然,
解除ViewControlleranimated
将不再工作。所以问题是您将
close
方法更改为什么

但在我开始之前,这个结构有两个问题。首先,如果在非ARC项目中执行此操作,则会泄漏控制器。更糟糕的是,如果使用ARC执行此操作,则会出现异常,因为控制器在超出范围时将被释放(如果启用僵尸,则会看到有意义的错误)。这个问题的典型答案是使
B*bcontrol
和A的ivar,或者执行类似的操作,这样就不会释放指向
bcontrol
的指针。这就解决了眼前的问题

其次,更大的问题是,整个构造(将控制器的视图添加为另一个视图的子视图)通常不是一个好主意,因为视图控制器层次结构和视图层次结构不同步。(对于这些问题的冗长讨论,请注意。)您可能无法获得轮换事件。您不知道还会发生什么(因为iOS假定它可以导航视图控制器层次结构,以便将消息发送到各个控制器)。总之,获取另一个视图控制器的视图并将其添加为当前视图的子视图不是一个好主意。唯一一次这样做是,如果您正在进行正版视图控制器包含,并且已经完成了
addChildViewController
didMoveToParentViewController
,并且您只想获得第一个视图(参见上述视频)

但是,如果您决定执行
[self.view addSubview:bcontrol.view]构造,则显然不能在B的
close
方法中使用相同的
dismissViewControllerAnimated
。从A的视图中删除B的视图的逻辑方法是
[self.view removeFromSuperView]。但接下来您面临一个挑战,即如何确保您的a类现在清理您最初创建的B实例,否则您将出现泄漏


总之,这不是一个好主意。坚持使用
presentViewController
(您将使用
dismissViewControllerAnimated
)或
pushViewController
(您将使用
popViewControllerAnimated
)或使用视图控制器控制。考虑到您讨论了“关闭”按钮的想法,这意味着一个UI真正适合于
presentViewController
pushViewController
模型。

我假设如果他使用上面列出的代码,他一定不能使用ARC,否则我怀疑他会在视图出现时出现异常,在按下
关闭
按钮后就不会了,不是吗?我只是觉得很奇怪,他讨论了如何更改我们创建B的视图,但没有提到他在
close
方法后面使用了什么代码,也没有提到在呈现新视图的两种技术中代码是如何更改的。在视图控制器中的代码被执行之前,不一定会有错误。因为它不是控制器层次结构的一部分,所以它不会得到正常的“出现”回调。我可以相信,点击按钮是一个转折点。(我不知道从他们的控制器中取出视图并将它们传递给不同的控制器的做法是从哪里来的,但我希望现在就停止!:)是的,我不确定在视图控制器本身超出范围之前,视图控制器的内容会执行多少。看起来所有初始内容,例如
viewDidLoad
viewwillbeen
viewdidbeen
等,都发生在
B*
解除分配之前,但用户从该点开始启动的任何操作都将导致异常。