我正在使用故事板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被声明(非原子,强)属性,如果这会产生不希望的行为,我可以改变它。
答案 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;
}
}