MFMailComposeViewController crashing while dismissModalViewControllerAnimated in iOS5

血红的双手。 提交于 2019-12-04 09:31:33

You need to keep a strong reference to MFMailComposeViewController *mailer in your class, and after you dismiss it you can null that reference. Ask me how I know this :-)

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

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

Later on, when completely done with it, you simply "mailer = nil;" to release it.

EDIT: What I do and suggest is to use a block to the main queue to do the release. If you just use 'self.mailer = nil' then the release happens after the final delegate method has finished and you are for sure no longer using it.

EDIT2: This crash does not happen all the time on all devices - I would say its somewhat of a race condition between when you receive the final delegate method and when its finished its work. Apple does not say anything about holding a reference one way or the other - however, general practice on Apple products is to assume any object you get is "on loan" through one runLoop, and thereafter if you want to keep a reference you have to retain the object.

If your are having sharekit framework implemented in your code goto SHK.m and change

        [[currentView parentViewController] dismissModalViewControllerAnimated:YES];

to

        [currentView  dismissModalViewControllerAnimated:YES];

This will solve your problem.

Thanks everyone for response.

and also comment these lines

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

HI you can use following code to send mail mail app will not send any email form simulator you have to install you application on device. EXE_BAD_ACCESS comes when you try to access the object they are not in memory and remamber device is case sensitive.

-(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]];
}

Since the stop of the stack is 0x00000000, I'm assuming some code inside UIKit is jumping to a nil function pointer. Enable Zombies and see if you get a zombie object access error. (Edit your project scheme, under Run/Debug, Diagnostics tab, check "Enable Zombie Objects")

try this code, this works well without crashing.. contact us method is button target selector..

    -(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]];
}
deleted_user

If you are using ARC, the controller object will have been released before you call dismiss.

Retain the object somewhere besides a stack allocated variable.

Have you set delegate MFMailComposeViewControllerDelegate in .h file. I have faced such problem in past. And error was very minor. Please check delegate in .h file.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!