【问题标题】:Crashing after dismissing a Modal View Controller关闭模态视图控制器后崩溃
【发布时间】:2011-09-28 06:46:14
【问题描述】:

我正在展示和关闭模态视图控制器。我使用委托,所以我在 Parent 处关闭了 modalView。

- (void)launchDrawingSection{

    drawingSectionViewController = [[DrawingSectionViewController alloc] init];
    drawingSectionViewController.modalTransitionStyle = UIViewAnimationTransitionFlipFromLeft;
    drawingSectionViewController.drawingModalDelegate = self;
    [self presentModalViewController:drawingSectionViewController animated:YES];
}


- (void)didDismissDrawingModalView{

    NSLog(@"didDismissDrawingModalView");
    [drawingSectionViewController release];
    [self dismissModalViewControllerAnimated:YES];
}

调用 ModalView 中的 dealloc 方法后应用崩溃。

我呈现和关闭模态视图控制器的方式有问题吗?有什么想法吗?

【问题讨论】:

  • 如果它在模态视图控制器的dealloc 中崩溃,您可能已经过度释放其实例变量之一。有崩溃日志吗?
  • didDismissDrawingModalView 方法何时被调用?
  • 退出 ModalView 时调用。这是我使用的一种协议方法,因此 ParentView 是关闭模态视图的方法。
  • “退出”ModalView 是什么意思? DrawingModalView 被呈现为模态视图控制器。它应该退出的唯一方法是“解雇”。由于您的函数名称“didDismissDrawingModalView”表明 DrawingModalView 已经“确实”关闭了,那么为什么它再次被关闭?
  • 这只是一个糟糕的函数名。在 ModalView 中,我有一个名为 DismissView 的函数,它告诉 Delegate(ParentView) 函数 didDismissDrawingModalView 关闭视图。所以它只被解雇一次。

标签: iphone objective-c ios4


【解决方案1】:

在解雇之前不要释放。

- (void)launchDrawingSection{

        drawingSectionViewController = [[DrawingSectionViewController alloc] init];

        drawingSectionViewController.modalTransitionStyle =          UIViewAnimationTransitionFlipFromLeft;

        drawingSectionViewController.drawingModalDelegate = self;

        [self presentModalViewController:drawingSectionViewController animated:YES];

        [drawingSectionViewController release];    


}




- (void)didDismissDrawingModalView{
    NSLog(@"didDismissDrawingModalView");

    [self dismissModalViewControllerAnimated:YES];


}

【讨论】:

  • 不释放它会导致内存泄漏,不是吗?那我在哪里发布呢?如果我在解雇后放置它,它仍然会崩溃。
  • 不,我们在展示后立即发布了它们,所以不要在那里泄漏。
  • 发生了什么,如果有泄漏请告诉我
  • 最好尽快发布,不要越早发布。在这种情况下,您的模态 VC 在您呈现时由系统保留(并在您关闭时由系统释放)。因此,正如 madhu 所说,您可以在 presentModalViewController 调用之后立即释放它。其实应该是launchDrawingSection里面的一个局部变量。但是,正如您发现的那样,您最初的崩溃并不是因为这个原因,因为您在 didDismiss 中的发布只是延迟了,而不是重复。
  • 要回答您的 dealloc 问题,这取决于“父”对象是否保留它。如果它确实正确地保留它,那么释放控制器的保留只会减少释放计数,但不会减少到零。但是,如果它是分配,而不是保留,那么是的,它可能会导致崩溃。简单规则:alloc、new、copy和retain(包括retaining setter)全部递增;释放减量(并且自动释放延迟减量)。
【解决方案2】:

您的 Modal View Controller 基础不明确。 如果您仅使用委托协议来通知绘图部分的父控件关闭绘图部分控制器,那么这是无用的。因为,以下事情可以在不使用委托的情况下完成您的工作。

// Present drawing section.
- (void)launchDrawingSection{

    drawingSectionViewController = [[DrawingSectionViewController alloc] init];
    drawingSectionViewController.modalTransitionStyle = UIViewAnimationTransitionFlipFromLeft;
    drawingSectionViewController.drawingModalDelegate = self;
    [self presentModalViewController:drawingSectionViewController animated:YES];
    [drawingSectionViewController release];
}

// (Put this in Drawing Section View Controller). This function dismisses drawing section.
- (void)dismissActionEvent{
    // Drawing section view controller is asking its parent to dismiss it.
    [self.parentViewController dismissModalViewControllerAnimated:YES];
}

要清楚地了解呈现和关闭模态视图控制器的工作原理,请参阅我的回答here

【讨论】:

  • 我知道模态视图控制器是如何工作的。我正在使用 Apple 的首选技术来解除委托的 ModalView。让我告诉你,我不知道有不同的解雇方式。很高兴知道一些替代方案。
  • 好吧,虽然这确实有效,但 Apple 显然与你不同:“虽然有几种技术可以通知父视图控制器它应该关闭其模态呈现的子视图,但首选技术是委托。. .. 这种使用委托来管理与模态视图控制器的交互与其他技术相比具有一些关键优势:委托对象有机会在视图控制器被解除之前验证或合并来自模态视图控制器的更改。第二,使用代表促进更好的封装......”
  • 我同意“封装”的说法。谢谢。我从这里学到了一些东西:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-21
  • 1970-01-01
  • 2011-06-11
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多