0

I have this simple function to write mail on ios 8.0, xcode 6.1. Nothing special, it ever worked till ios 8.0 said hello. The function sendMail sends a mail when a button gets tapped (set via storyboard). I debugged it and the code seems ok, but it crashes with a EXC_BAD_ACCESS code=1 error whenever you're supposed to return back to the main app, like when you tap the send or dismiss button of the MFMailComposeViewController. It seems to me that my View, i mean the view calling the MFMailComposeViewController is deallocated when the MFMailComposeViewController is called, so that when it get dismissed, there's nothing to return on. Some ideas to solve the problem? [The function didFinishWithResult is never reached: the crash happens before.]

EDIT: To be precise it crashes with bad_access if in the presentViewController i set animated to NO. If it is YES it complain about 'unbalanced calls to begin/end appearance transitions' and tapping send/dismiss does nothing (it not returns. The mail view is alive but tap button does nothing)

EDIT: I am right about the deallocation. He have the same problem but it does not seems to have a valid solution MFMailComposeViewController crash in iOS6 ARC In my case Arc is turned off and i cannot turn it on for various reasons. The theory is confirmed by zombie instrument. It says 'An Objective-C message was sent to a deallocated 'View' object (zombie) at address: 0x14e01720'

View.h
included MFMailComposeViewControllerDelegate and imported
#import <MessageUI/MFMailComposeViewController.h>

View.m
-(IBAction)sendEmail:(id)sender{

NSString *mailDiretta=emailText.currentTitle;

composer = [[MFMailComposeViewController alloc] init];
[composer setMailComposeDelegate:self];
if ([MFMailComposeViewController canSendMail]) {
    [composer setToRecipients:[NSArray arrayWithObjects:mailDiretta, nil]];
    [composer setSubject:@"Infos"];
    [composer setMessageBody:@"Write to me, dude!" isHTML:NO];
    [composer setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
    [self presentViewController:composer animated:YES completion:NULL];
    [composer release];
} else
[composer release];
}

// function below is never reached
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
if (error) {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"error"
                                                    message:[NSString stringWithFormat:@"error %@", [error description]]
                                                   delegate:nil cancelButtonTitle:@"dismiss" otherButtonTitles:nil, nil];
    [alert show];
    [self dismissViewControllerAnimated:YES completion:NULL];
} else {
    [self dismissViewControllerAnimated:YES completion:NULL];
}
}
Community
  • 1
  • 1
Sasha Grievus
  • 2,566
  • 5
  • 31
  • 58

1 Answers1

1

I would assume it's because you're releasing the composer before it finishes.

[composer release];

EDIT: How is this property initialized and why is it a property? Create it in the method and try. Also, your unbalanced calls are happening because you're animating a UIAlert at the same time you are animating the mail controller dismiss. Each needs to finish prior to prevent that message.

composer = [[MFMailComposeViewController alloc] init];

Try to remove the property and initialize in the function.

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

Make sure you added the delegate properly as well.

#import <MessageUI/MessageUI.h>
@interface YourViewController : UIViewController <MFMailComposeViewControllerDelegate> 

Set your delegate like this

composer.mailComposeDelegate = self;

For the unbalanced calls, rearrange your alert like this...

[self dismissViewControllerAnimated:YES completion:NULL];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"error"
                                                message:[NSString stringWithFormat:@"error %@", [error description]]
                                               delegate:nil cancelButtonTitle:@"dismiss" otherButtonTitles:nil, nil];
[alert show];

EDIT 2: After seeing your comment about not being able to use ARC due to one class I would advice you to simply set a -fno-objc-arc compiler flag on that class and enable ARC across your project and make your life WAY easier. Disable Automatic Reference Counting for Some Files

Community
  • 1
  • 1
Mark McCorkle
  • 9,349
  • 2
  • 32
  • 42
  • did it, now crashes if animated is YES, too :D – Sasha Grievus Nov 10 '14 at 22:00
  • Ok i'm officially confused. I wrote some nslog inside didFinishWithResult. It never print them, which make me think that the function never gets called, but if i apply your suggestion about the alert, the app stops crashing randomly (sometimes crashes sometimes not)... It does not solve the problem beacuse the buttons sendd/dismiss seems to do nothing, not returning to the main app unfortunately. – Sasha Grievus Nov 10 '14 at 22:05
  • Your delegate is the issue. – Mark McCorkle Nov 10 '14 at 22:07
  • no difference setting the delegate in this way and delegate set properly. sigh – Sasha Grievus Nov 10 '14 at 22:09
  • You are definitely only calling that method once, correct? – Mark McCorkle Nov 10 '14 at 22:20
  • Yes, it's linked to a button as an IBAction... You saw my edit about deallocation? I'm running zombie to confirm it – Sasha Grievus Nov 10 '14 at 22:23
  • Et voila! 'An Objective-C message was sent to a deallocated 'View' object (zombie) at address: 0x14e01720'. View gets deallocated in some moment when the mail view is called – Sasha Grievus Nov 10 '14 at 22:25
  • 1
    Probably your viewWillDissapear method. Make sure you are allocating your properties properly. These need to be retained and released properly if you are not using ARC. Please add that your project is not ARC in future questions for much faster answers since ARC is now standard. ;-) – Mark McCorkle Nov 10 '14 at 22:28
  • ... ... ... Cannot believe it. There was a line of code inherited from a wild copy/paste of the view code that was doing [self.navigationController popToRootViewControllerAnimated:NO]; in ViewWillDisappear Thank you very much!! It was about two weeks (i swear, i'm SUCH an idiot) that i was struggling with this! I'll do what you suggest to do with arc. Unfortunately i use an old module working perfectly, but not supporting arc, that i cannot still get rid off and so not arc for me. Thank you a lot! – Sasha Grievus Nov 10 '14 at 22:35
  • You do realize you can still use ARC and just single out the one class that is not ARC compatible, right? I would advise you to simply set a flag on the class in question and leave your project ARC for multiple reasons. http://stackoverflow.com/questions/6448874/disable-automatic-reference-counting-for-some-files – Mark McCorkle Nov 11 '14 at 13:15
  • Wow, i wasn't aware of this. I'll surely try. By the way, just for curiosity, you think there was an instrument that could pointing out more precisely the behavior that caused the error, beyond the good sense (that is supposed to be installed in people, but sometimes fails) – Sasha Grievus Nov 11 '14 at 14:35
  • 1
    The correct instrument would be breakpoints. If you place a breakpoint and step through it (and out) one by one you'll see the problem code in question more than likely. Understanding the sequence that viewController's delegates take is also fundamental to debugging view stack hierarchal changes such as presenting or "popping" a controller. Good luck! p.s. You'll love ARC – Mark McCorkle Nov 11 '14 at 16:35