MFMailComposeViewController轰然而dismissModalViewCont

2019-07-30 16:29发布

我在我的孔德提供邮件功能,但发送邮件,或者当我想取消的邮件将被撞毁后使用MFMailComposeViewController。

下面是我的代码:

(IBAction)FnForPlutoSupportEmailButtonPressed:(id)sender {
{
    if ([MFMailComposeViewController canSendMail])
    {
        MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];

        mailer.mailComposeDelegate = self;

        [mailer setSubject:@"Need help from Pluto support team"];

        NSArray *toRecipients = [NSArray arrayWithObjects:@"support@myplu.to",nil];
        [mailer setToRecipients:toRecipients];


        NSString *emailBody = @"";

        [mailer setMessageBody:emailBody isHTML:NO];

        //mailer.modalPresentationStyle = UIModalPresentationPageSheet;

        [self presentModalViewController:mailer animated:YES];

    }
    else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Failure"
                                                        message:@"Your device doesn't support the composer sheet"
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles: nil];
        [alert show];
    }
} }

    (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
// Notifies users about errors associated with the interface    
switch (result)
    {       case MFMailComposeResultCancelled:
                        break;
                    case MFMailComposeResultSaved:
                        break;
                    case MFMailComposeResultSent:
                        break;
                    case MFMailComposeResultFailed:
                        break;
                    default:
                        break;
    } 
    [self dismissModalViewControllerAnimated:YES];
     }

我已阅读所有的博客文章,但没有找到解决办法, 这个博客帖子是有这个很好的解释,但按照这个我不是在viewDidLoad中或viewdidappear提出我的看法控制器。

我越来越EXE_BAD_ACCESS,以下是崩溃日志:

**

> #0  0x00000000 in ?? ()
> #1  0x01dc5aa4 in -[UIViewController _setViewAppearState:isAnimating:] ()
> #2  0x01dc5f47 in -[UIViewController __viewDidDisappear:] ()
> #3  0x01dc6039 in -[UIViewController _endAppearanceTransition:] ()
> #4  0x01dd2e7e in -[UIViewController(UIContainerViewControllerProtectedMethods) endAppearanceTransition] ()
> #5  0x01fc8de1 in -[UIWindowController transitionViewDidComplete:fromView:toView:] ()
> #6  0x01da334b in -[UITransitionView notifyDidCompleteTransition:] ()
> #7  0x01da3070 in -[UITransitionView _didCompleteTransition:] ()
> #8  0x01da531b in -[UITransitionView _transitionDidStop:finished:] ()
> #9  0x01d23fb6 in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] ()
> #10 0x01d24154 in -[UIViewAnimationState animationDidStop:finished:] ()
> #11 0x0163bbce in CA::Layer::run_animation_callbacks ()
> #12 0x03664fe4 in _dispatch_client_callout ()
> #13 0x03655997 in _dispatch_main_queue_callback_4CF ()
> #14 0x012c03b5 in __CFRunLoopRun ()
> #15 0x012bf804 in CFRunLoopRunSpecific ()
> #16 0x012bf6db in CFRunLoopRunInMode ()
> #17 0x030f1913 in GSEventRunModal ()
> #18 0x030f1798 in GSEventRun ()
> #19 0x01ce82c1 in UIApplicationMain ()

**

按照苹果的他们提到的iOS 5的更新文件:

presentModalViewController:动画:

呈现由给定的视图控制器向所述用户管理的模式图。 (已过时使用。 presentViewController:animated:completion:代替。)

- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated
Parameters

驳回这是由接收器呈现的视图控制器。 (不推荐使用。 dismissViewControllerAnimated:completion:代替。)

- (void)dismissModalViewControllerAnimated:(BOOL)animated

我也试过,但它仍然崩溃

Answer 1:

你需要在你的类的强引用MFMailComposeViewController *邮件,你解雇后,你可以空该引用。 问我是怎么知道这个:-)

@implememtation MyClass
{
    MFMailComposeViewController *mailer;
}
...

(IBAction)FnForPlutoSupportEmailButtonPressed:(id)sender {
{
    if ([MFMailComposeViewController canSendMail])
    {
        /* USE IVAR */mailer = [[MFMailComposeViewController alloc] init];

后来,当完全用它做,你只是“邮件=零;” 将其释放。

编辑:我做的,什么建议是使用块到主队列做的释放。 如果你只是使用“self.mailer =零”,那么发布最终的委托方法结束后发生,你是肯定的使用不再像。

EDIT2:这个崩溃不会发生在所有设备上所有的时间 - 我想说的有点它当您收到最终的委托方法,当它完成其工作之间的竞争条件。 苹果并没有说明保持参照的一种方式或其他任何东西 - 但是,一般的苹果产品的做法是假设你得到任何对象是“借出”通过一个runLoop,此后,如果你想使你有一个参考保留的对象。



Answer 2:

如果你是在你的代码转到SHK.m和变革实施sharekit框架

        [[currentView parentViewController] dismissModalViewControllerAnimated:YES];

        [currentView  dismissModalViewControllerAnimated:YES];

这将解决您的问题。

谢谢大家的响应。

而且这些注释行

SHKSwizzle([MFMailComposeViewController class], @selector(viewDidDisappear:), @selector(SHKviewDidDisappear:));
if (NSClassFromString(@"MFMessageComposeViewController") != nil) SHKSwizzle([MFMessageComposeViewController class], @selector(viewDidDisappear:), @selector(SHKviewDidDisappear:));


Answer 3:

HI,您可以使用下面的代码来发送邮件,邮件程序将不会发送您必须安装您在设备应用程序的任何电子邮件形式模拟器。 EXE_BAD_ACCESS来当您尝试访问他们不是在内存中的对象和remamber设备是区分大小写的。

-(void)sendMail:(id)sender
{
    //create instance of class at runtime.
    Class mailComposer = (NSClassFromString(@"MFMailComposeViewController"));
if (mailClass != nil)
{
        // check the current device is configured for sending emails
        //if it is not configured for mail you open mail application on device.
    if ([mailClass canSendMail])
    {
        [self displayComposerSheet];
    }
    else
    {
        [self launchMailAppOnDevice];
    }
}
else
{
    [self launchMailAppOnDevice];
}

}
-(void)displayComposerSheet 
 {
MFMailComposeViewController *mailPicker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;

[picker setSubject:@"Welcome!"];

    //recipients

NSArray *to = [NSArray arrayWithObject:@"jhon@example.com"];  

[picker setToRecipients:toRecipients];

    // Attach an image
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Default" ofType:@"png"];
NSData *imageData = [NSData dataWithContentsOfFile:filePath];
[picker addAttachmentData:myData mimeType:@"image/png" fileName:@"Default"];

    // Set email body text
    //NSString *emailBody = @"......!";
    //[picker setMessageBody:emailBody isHTML:NO];

[self presentModalViewController:picker animated:YES];
[picker release];
}


- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:   (MFMailComposeResult)result error:(NSError*)error 
{   
message.hidden = NO;
    // Notifies users about errors associated with the interface
switch (result)
{

    case MFMailComposeResultCancelled:
        message.text = @"Canceled";
        break;
    case MFMailComposeResultSaved:
        message.text = @"Saved";
        break;
    case MFMailComposeResultSent:
        message.text = @"Sent";
        break;
    case MFMailComposeResultFailed:
        message.text = @"Failed";
        break;
    default:
        message.text = @"Not sent";
        break;
}
[self dismissModalViewControllerAnimated:YES];
}

-(void)launchMailAppOnDevice
{
NSString *recipients = @"";
NSString *body = @"";

NSString *email1 = [NSString stringWithFormat:@"%@%@", recipients, body];
email1 = [email1 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:email1]];
}


Answer 4:

由于堆栈的停止是0x00000000 ,我假设里面UIKit的一些代码是跳跃到零函数指针。 启用僵尸,看看你得到一个僵尸对象访问错误。 (编辑您的项目方案,在运行/调试,诊断选项卡,勾选“启用僵尸对象”)



Answer 5:

试试这个代码,这个效果很好没有崩溃..联系我们的方法是按钮目标选择..

    -(void)ContactUs:(UIButton*)button
    {
        Class mailClass = (NSClassFromString(@"MFMailComposeViewController"));
        if (mailClass != nil)
        {
            // We must always check whether the current device is configured for sending emails
            if ([mailClass canSendMail])
            {
                [self displayComposerSheet];
            }
            else
            {
                [self launchMailAppOnDevice];
            }
        }
        else
        {
            [self launchMailAppOnDevice];
        }

    }

-(void)displayComposerSheet 
{
    MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
    picker.mailComposeDelegate = self;

    //[picker setSubject:@"Hello from California!"];

    // Set up recipients

    NSArray *toRecipients = [NSArray arrayWithObject:@"info@imp.co.in"]; 
    //NSArray *ccRecipients = [NSArray arrayWithObjects:@"second@example.com", @"third@example.com", nil]; 
    //NSArray *bccRecipients = [NSArray arrayWithObject:@"fourth@example.com"]; 

    [picker setToRecipients:toRecipients];
    //[picker setCcRecipients:ccRecipients];    
    //[picker setBccRecipients:bccRecipients];

    // Attach an image to the email
    /*NSString *path = [[NSBundle mainBundle] pathForResource:@"rainy" ofType:@"png"];
     NSData *myData = [NSData dataWithContentsOfFile:path];
     [picker addAttachmentData:myData mimeType:@"image/png" fileName:@"rainy"];*/

    // Fill out the email body text
    //NSString *emailBody = @"It is raining in sunny California!";
    //[picker setMessageBody:emailBody isHTML:NO];

    [self presentModalViewController:picker animated:YES];
    [picker release];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error 
{   
    message.hidden = NO;
    // Notifies users about errors associated with the interface
    switch (result)
    {

        case MFMailComposeResultCancelled:
            message.text = @"Canceled";
            break;
        case MFMailComposeResultSaved:
            message.text = @"Saved";
            break;
        case MFMailComposeResultSent:
            message.text = @"Sent";
            break;
        case MFMailComposeResultFailed:
            message.text = @"Failed";
            break;
        default:
            message.text = @"Not sent";
            break;
    }
    [self dismissModalViewControllerAnimated:YES];
}

-(void)launchMailAppOnDevice
{
    NSString *recipients = @"";
    NSString *body = @"";

    NSString *email1 = [NSString stringWithFormat:@"%@%@", recipients, body];
    email1 = [email1 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:email1]];
}


Answer 6:

如果您正在使用ARC,控制器对象将被调用解雇之前发布。

地方保留对象除了堆栈分配的变量。



Answer 7:

你有没有设置.h文件中委托MFMailComposeViewControllerDelegate。 我已经在过去面临过这样的问题。 和错误是非常小的。 请.h文件中检查委托。



文章来源: MFMailComposeViewController crashing while dismissModalViewControllerAnimated in iOS5