【问题标题】:Why calling MFMailComposeViewController deallocates the view that called it?为什么调用 MFMailComposeViewController 会释放调用它的视图?
【发布时间】:2015-01-07 08:03:44
【问题描述】:

我有这个简单的功能可以在 ios 8.0、xcode 6.1 上写邮件。没什么特别的,它一直工作到 ios 8.0 打招呼。 当一个按钮被点击(通过故事板设置)时,函数 sendMail 会发送一封邮件。我对其进行了调试,代码看起来还可以,但是当您应该返回主应用程序时,它会崩溃并出现 EXC_BAD_ACCESS code=1 错误,例如当您点击 MFMailComposeViewController 的发送或关闭按钮时。在我看来,我的视图,我的意思是调用 MFMailComposeViewController 的视图在调用 MFMailComposeViewController 时被释放,因此当它被解雇时,没有什么可返回的。解决问题的一些想法? [函数 didFinishWithResult 从未到达:崩溃发生在之前。]

编辑:准确地说,如果在 presentViewController 中我将动画设置为 NO,它会因 bad_access 而崩溃。如果是,它会抱怨“开始/结束外观转换的不平衡调用”并且点击发送/关闭什么都不做(它不会返回。邮件视图是活动的,但点击按钮什么都不做)

编辑我对解除分配是正确的。他有同样的问题,但似乎没有有效的解决方案MFMailComposeViewController crash in iOS6 ARC 在我的情况下,Arc 已关闭,由于各种原因我无法打开它。僵尸仪器证实了这一理论。它说“一个 Objective-C 消息已发送到地址为:0x14e01720 的已释放“视图”对象(僵尸)”

View.h
included MFMailComposeViewControllerDelegate and imported
#import <MessageUI/MFMailComposeViewController.h>

View.m
-(IBAction)sendEmail:(id)sender{

NSString *mailDiretta=emailText.currentTitle;

composer = [[MFMailComposeViewController alloc] init];
[composer setMailComposeDelegate:self];
if ([MFMailComposeViewController canSendMail]) {
    [composer setToRecipients:[NSArray arrayWithObjects:mailDiretta, nil]];
    [composer setSubject:@"Infos"];
    [composer setMessageBody:@"Write to me, dude!" isHTML:NO];
    [composer setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
    [self presentViewController:composer animated:YES completion:NULL];
    [composer release];
} else
[composer release];
}

// function below is never reached
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
if (error) {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"error"
                                                    message:[NSString stringWithFormat:@"error %@", [error description]]
                                                   delegate:nil cancelButtonTitle:@"dismiss" otherButtonTitles:nil, nil];
    [alert show];
    [self dismissViewControllerAnimated:YES completion:NULL];
} else {
    [self dismissViewControllerAnimated:YES completion:NULL];
}
}

【问题讨论】:

  • 它在哪一行崩溃?解雇?
  • 它不会在我的代码上崩溃。发送邮件的视图被调用,但是当你点击发送/关闭,而不是返回并执行 didFinishWithResult 时,它崩溃了。

标签: ios objective-c iphone


【解决方案1】:

我认为这是因为您在作曲家完成之前释放了它。

[composer release];

编辑:这个属性是如何初始化的,为什么它是一个属性?在方法中创建它并尝试。此外,您的不平衡呼叫正在发生,因为您在为邮件控制器关闭动画的同时为 UIAlert 设置动画。每个都需要在阻止该消息之前完成。

composer = [[MFMailComposeViewController alloc] init];

尝试移除属性并在函数中初始化。

MFMailComposeViewController *composer = [[MFMailComposeViewController alloc] init];

确保您也正确添加了委托。

#import <MessageUI/MessageUI.h>
@interface YourViewController : UIViewController <MFMailComposeViewControllerDelegate> 

这样设置你的委托

composer.mailComposeDelegate = self;

对于不平衡的通话,请像这样重新排列您的警报...

[self dismissViewControllerAnimated:YES completion:NULL];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"error"
                                                message:[NSString stringWithFormat:@"error %@", [error description]]
                                               delegate:nil cancelButtonTitle:@"dismiss" otherButtonTitles:nil, nil];
[alert show];

编辑 2: 在看到您关于由于一个类而无法使用 ARC 的评论后,我建议您只需在该类上设置一个 -fno-objc-arc 编译器标志,并在您的项目中启用 ARC,让您的生活更轻松。 Disable Automatic Reference Counting for Some Files

【讨论】:

  • 做到了,如果动画是YES,现在也会崩溃:D
  • 好吧,我很困惑。我在 didFinishWithResult 里面写了一些 nslog。它从不打印它们,这让我认为该函数永远不会被调用,但如果我应用你关于警报的建议,应用程序会停止随机崩溃(有时崩溃有时不会)......它不能解决问题,因为按钮已发送/dismiss 似乎什么也没做,不幸的是没有返回主应用程序。
  • 你的代表是问题。
  • 可能是你的 viewWillDissapear 方法。确保您正确分配属性。如果您不使用 ARC,则需要正确保留和释放这些内容。请在未来的问题中添加您的项目不是 ARC,以便更快地得到答案,因为 ARC 现在是标准的。 ;-)
  • 正确的工具是断点。如果您放置一个断点并逐个执行(并退出),您很可能会看到有问题的问题代码。了解 viewController 的委托所采用的顺序也是调试视图堆栈层次结构更改(例如呈现或“弹出”控制器)的基础。祝你好运! p.s.你会爱上 ARC
猜你喜欢
  • 2010-12-14
  • 2014-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-20
  • 2013-12-23
  • 1970-01-01
相关资源
最近更新 更多