MFMailComposeViewController crash in iOS6 ARC

为君一笑 提交于 2019-12-11 12:38:31

问题


Iam presenting MFMailComposeViewController from my custom class(not a viewController). In iOS5 it is working fine but in iOS6 it is getting crash immediately after presenting the compose sheet. I found the issue the dealloc method is getting called after presenting the view, so self is deallocating. Due to this mailcomposer cannot call the delegate method on self so it is crashing. I didnt get a solution for that. Am using ARC. How to prevent self from deallocating until the delegate method is getting called?

  -(void)shareOnViewController:(UIViewController *)viewController  completion:(ShareCompletionHandler)completion
{

  if ([MFMailComposeViewController canSendMail]) {

    MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
    mailer.mailComposeDelegate = self;
    mailer.modalPresentationStyle = UIModalPresentationPageSheet;
    [mailer setSubject:[self.userInfo objectForKey:@"title"]];

    NSData *imageData = UIImagePNGRepresentation([self.userInfo objectForKey:@"image"]);
    if (imageData) {
        [mailer addAttachmentData:imageData mimeType:@"image/png" fileName:@"AttachedImage"];
    }


    NSURL *emailBody = [self.userInfo objectForKey:@"url"];
    if (![emailBody isEqual:@""]) {
        [mailer setMessageBody:[emailBody absoluteString] isHTML:NO];
    }

    [viewController presentModalViewController:mailer animated:YES];

   } else {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Unable to send mail"
                                                    message:@"Device is not configured to send mail"
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alert show];
   }

self.completionHandler = completion;

}

回答1:


According to me , The presentModalViewController method is deprecated in iOS 6.0 .

Instead you need to use

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion 

Else can you show the crash log ??




回答2:


  if ([MFMailComposeViewController canSendMail]) {
        MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc]
                                                     init];

    NSData *imageData = UIImagePNGRepresentation(image);
    mailComposer.mailComposeDelegate = self;
    [mailComposer setSubject:subject];
    NSArray * recipents = [NSArray arrayWithObjects:[NSString stringWithFormat:@"%@",NSLocalizedString(@"client_email", @"")],nil];

    [mailComposer setToRecipients:recipents];

    [mailComposer addAttachmentData:imageData mimeType:@"image/png" fileName:[NSString stringWithFormat:@"imageProfile-%@-%@",someId,lastname]];



    mailComposer.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;

    [vc presentViewController:mailComposer animated:YES completion:nil];
}
else
{
    UIAlertView *tmp = [[UIAlertView alloc]
                        initWithTitle:@"Email Account Not Found"
                        message:@"You need to setup an Email Account!"
                        delegate:self
                        cancelButtonTitle:nil
                        otherButtonTitles:@"Ok", nil];

    [tmp show];
}



回答3:


One of the possible root cause is ARC.

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

mailer will be auto-released as soon as the method body is fully executed.

You could create a reference to hold the object to avoid ARC releasing it before it is ready.

@property (nonatomic, strong) MFMailComposeViewController * composer;
....


self.composer = [[MFMailComposeViewController alloc] init];
...
[viewController presentViewController:self.composer animated:YES];

[Edited suggestion]

Sorry, I miss out the first part of your question where you were calling the method from another custom class.

I came across the similar situation also. In the end, I converted the "Custom Class" into a Singleton class.

#pragma mark Singleton Methods

+ (id)sharedInstance {
    static CustomClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

This will make sure the class will be retained nicely. But this will depend on the usage and design of the CustomClass. Just to share what I did.

[[CustomClass sharedInstance] shareOnViewController:vc completion:...];


来源:https://stackoverflow.com/questions/17057793/mfmailcomposeviewcontroller-crash-in-ios6-arc

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