问题
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