简体   繁体   中英

Thread 1: EXEC_BAD_ACCESS on MFMailComposeViewController's dismissModalViewController (tried iOS 5.1 , 5 , 4.3)

Ok, this has been haunting me for a while now...

I have checked and all the other questions/answers are with non ARC projects.

Whenever I present the MFMCvc and I quickly cancel the message I get the Thread1:EXEC_BAD_ACCESS error message on iPhones. Works fine on the iPad or if I let it sit for a bit (say 30 secs or more)

Any advise? (other than putting a timer and not dismissing until timer's up?)

BTW I'm doing the same with MFMessageComposeViewController and it works fine on both iPhone and iPad.

Here is my code to present it

if (([action isEqualToString:@"EMail"]) && contact.length>0)
{
    MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
    if([MFMailComposeViewController canSendMail]) {
        [mailViewController setSubject:@""];
        [mailViewController setMessageBody:@"" isHTML:NO];
        [mailViewController setToRecipients:[NSArray arrayWithObject:contact]];
        [mailViewController setMailComposeDelegate:self];
        [self presentModalViewController:mailViewController animated:NO];
    }
}

And here is where I dismiss it

-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
    {
        switch (result)
        {
            case MFMailComposeResultCancelled:
            {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Send EMail" message:@"EMail Has Been Cancelled"
                                                               delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
                [alert show];
            }
                break;
            case MFMailComposeResultFailed:
            {
                NSLog(@"Error");
            }
                break;
            case MFMailComposeResultSent:
            {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Send EMail" message:@"EMail Has Been Sent"
                                                               delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
                [alert show];
            }
                break;
            case MFMailComposeResultSaved:
            {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Send EMail" message:@"EMail Has Been Saved"
                                                               delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
                [alert show];
            }
                break;
            default:
                break;
        }
        [self dismissModalViewControllerAnimated:NO];
    }

1) Doesn't the line: [self dismissModalViewControllerAnimated:NO]; - need to be: [controller dismissModalViewControllerAnimated:NO]; ? You are wanting to dismiss the MFMailComposeViewController.

2) There may also be an issue with the MFMailComposeViewController not being retained. When I've used this class I've created a property for the controller. This might be worth trying.

// in the interface definition
 @property (nonatomic, strong) MFMailComposeViewController* mailComposer;

and then

// at creation time
if (([action isEqualToString:@"EMail"]) && contact.length>0)

if(![MFMailComposeViewController canSendMail]) return; // bail early if can't send mail

MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
[mailViewController setSubject:@""];
[mailViewController setMessageBody:@"" isHTML:NO];
[mailViewController setToRecipients:[NSArray arrayWithObject:contact]];
[mailViewController setMailComposeDelegate:self];
[self presentModalViewController:mailViewController animated:NO];

[self setMailComposer: mailViewController];
// if not using ARC then:  [mailViewController release];

and then in the didFinish

 [[self mailComposer] dismissModalViewControllerAnimated:YES];
 [self setMailComposer: nil];

Move [self dismissModalViewControllerAnimated:NO] to the top of your didFinishWithResult function. In other words, dismiss the mail view before showing the alert view. I'm not sure if this will eliminate your crash, but regardless, you should do this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM