正确的方法来删除或解除segue到达的ViewControllers

时间:2014-10-29 11:52:12

标签: ios objective-c uiviewcontroller interface-builder segue

我正在使用故事板segues在我的iPhone应用程序中从一个屏幕移动到另一个屏幕。前向分段A - > B - > C是当前的模态segue,在代码中执行如下(A到B,其中B是previewController):

-(void) prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender
{
   if ([segue.identifier isEqualToString:@"previewSegue"])
    preview = (previewController*)segue.destinationViewController;
    preview.player = self.player;
    preview.opponent = self.opponent;
   }
 }

我打电话给segue

[self performSegueWithIdentifier:@"previewSegue" sender:nil];

我使用Interface Builder来绘制segue,并且没有特别的原因,选择它是模态的(另一种选择是推送)。转换工作正常,所以我使用相同的逻辑从B移动到C.当审查屏幕(称为屏幕C)完成后,我在故事板上画了一个segue回到C布局上方的退出图标,并实现放松在viewControllerA中:

-(IBAction) unwindToViewController: (UIStoryboardSegue*)sender
{
UIViewController* sourceViewController = sender.sourceViewController;

if ([sourceViewController isKindOfClass:[reviewController class]]) // <--- this is C
{
    NSLog(@"Coming from REVIEW CONTROLLER!");

    // Dismiss everything related to C
    if (preview != nil) {
        [preview dismissC];
        preview = nil;
    }
}
}

我在B中写的dismissC函数如下:

- (IBAction) dismissC
{
NSLog(@"C dismissal called!");

// Release data so nothing points to it any longer, and it can go out of scope
if (reviewController != nil)
    reviewController = nil;  // <----reviewController points to C during segue B --> C

}

我的问题是,在我退回到A之后,C仍然在程序中闲逛。我知道这是因为C实例化了一些在C演示过程中播放音乐和声音效果的AVAudioPlayers。在C的退出代码期间,我确保停止所有这些音频播放器,使定时器无效,将vars设置为nil等。但是如果我退出C,即使音乐停止播放,我仍然听到由于用户在C中触摸过的东西。例如,有一个按钮在被触摸后几秒内在C中播放按压噪声,并且此后连续地在回声中播放,并且在C已经解开到A之后它仍然播放,并且可能被解雇。

如何正确摆脱C的所有内存?当然,用户可以通过segue A - > B - > C回到C,但是我想在那时分配新的B和新的C,而没有所有这些残留的噪音。我认为我必须对这些细分和放松做错事,因为一旦我回到A,我很确定C的所有痕迹都应该消失,甚至会延迟噪音。

编辑上下文:A是一个普通的ViewController,带有一个集合视图,用户可以滚动浏览一组专辑的视频/缩略图。当用户选择一个时,A将所选标题传递给B,这是视频的时间限制“预览”,在此期间广告播放,并且用户可以选择购买&amp;当计时器用完时,B会切换到C,这是另一个定时视图控制器,带有各种按钮,可以完成视频播放,例如静音,添加声音,录制评论等。 C上的计时器用完了,我希望程序回到A并从B和C中删除(释放)所有数据,这样当选择另一个标题时,B重新开始。当前行为是一个问题,因为我在调用ReviewController(C)之前停止的一些声音和音频播放器即使在用户返回到A之后也在后台退出播放。视频和C的其他元素不再可见,或崩溃程序,但停止的AudioPlayers的声音继续激活,我无法在调试器或任何东西中跟踪它们,所以我不知道谁指向他们,为什么他们没有被释放,等等C中的AVAudioPlayers被声明(非原子,强)属性,如果这会产生不希望的行为,我可以改变它。

2 个答案:

答案 0 :(得分:1)

我认为,当您想要解雇“C”时,最好的选择是使用:

[self dismissViewControllerAnimated:YES completion:nil];

这样,您不需要“返回”segue,只需关闭“C”视图并显示“B”视图。

而且,如果您需要停止或发布有关音频播放器(或任何您想要的)的内容,您可以使用“完成”块。

我希望这能帮到你!

答案 1 :(得分:0)

我无法保证此代码有效,因为您在其他地方存在内存泄漏。 但我认为你的代码应该是这样的:

-(IBAction) unwindToViewController: (UIStoryboardSegue*)sender
{
    if (preview == sender.sourceViewController)
    {
        NSLog(@"Coming from REVIEW CONTROLLER!");
        preview = nil;
    }
}