4

メール機能を提供するためにコンデでMFMailComposeViewControllerを使用していますが、メールを送信した後、またはメールをキャンセルしたいときにクラッシュします。

以下は私のコードです:

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

        mailer.mailComposeDelegate = self;

        [mailer setSubject:@"Need help from Pluto support team"];

        NSArray *toRecipients = [NSArray arrayWithObjects:@"support@myplu.to",nil];
        [mailer setToRecipients:toRecipients];


        NSString *emailBody = @"";

        [mailer setMessageBody:emailBody isHTML:NO];

        //mailer.modalPresentationStyle = UIModalPresentationPageSheet;

        [self presentModalViewController:mailer animated:YES];

    }
    else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Failure"
                                                        message:@"Your device doesn't support the composer sheet"
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles: nil];
        [alert show];
    }
} }

    (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
// Notifies users about errors associated with the interface    
switch (result)
    {       case MFMailComposeResultCancelled:
                        break;
                    case MFMailComposeResultSaved:
                        break;
                    case MFMailComposeResultSent:
                        break;
                    case MFMailComposeResultFailed:
                        break;
                    default:
                        break;
    } 
    [self dismissModalViewControllerAnimated:YES];
     }

私はすべてのブログ投稿を読みましたが、解決策は見つかりませんでした。このブログ投稿にはこれについての十分な説明がありますが、これにより、viewdidloadまたはviewdidappearでビューコントローラーを表示していません。

EXE_BAD_ACCESSを取得しています。クラッシュログは次のとおりです。

****

> #0  0x00000000 in ?? ()
> #1  0x01dc5aa4 in -[UIViewController _setViewAppearState:isAnimating:] ()
> #2  0x01dc5f47 in -[UIViewController __viewDidDisappear:] ()
> #3  0x01dc6039 in -[UIViewController _endAppearanceTransition:] ()
> #4  0x01dd2e7e in -[UIViewController(UIContainerViewControllerProtectedMethods) endAppearanceTransition] ()
> #5  0x01fc8de1 in -[UIWindowController transitionViewDidComplete:fromView:toView:] ()
> #6  0x01da334b in -[UITransitionView notifyDidCompleteTransition:] ()
> #7  0x01da3070 in -[UITransitionView _didCompleteTransition:] ()
> #8  0x01da531b in -[UITransitionView _transitionDidStop:finished:] ()
> #9  0x01d23fb6 in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] ()
> #10 0x01d24154 in -[UIViewAnimationState animationDidStop:finished:] ()
> #11 0x0163bbce in CA::Layer::run_animation_callbacks ()
> #12 0x03664fe4 in _dispatch_client_callout ()
> #13 0x03655997 in _dispatch_main_queue_callback_4CF ()
> #14 0x012c03b5 in __CFRunLoopRun ()
> #15 0x012bf804 in CFRunLoopRunSpecific ()
> #16 0x012bf6db in CFRunLoopRunInMode ()
> #17 0x030f1913 in GSEventRunModal ()
> #18 0x030f1798 in GSEventRun ()
> #19 0x01ce82c1 in UIApplicationMain ()

****

iOS 5用のアップルの更新されたドキュメントによると、彼らは言及しました:

presentModalViewController:animated:

指定されたViewControllerによって管理されるモーダルビューをユーザーに提示します。(非推奨。presentViewController:animated:completion:代わりに使用してください。)

- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated
Parameters

受信者によって提示されたビューコントローラを閉じます。(非推奨。dismissViewControllerAnimated:completion:代わりに使用してください。)

- (void)dismissModalViewControllerAnimated:(BOOL)animated

私もこれを試しましたが、それでもクラッシュします

4

7 に答える 7

5

クラスで MFMailComposeViewController *mailer への強い参照を保持する必要があります。それを閉じた後、その参照を null にすることができます。どうやってこれを知っているのか聞いてください:-)

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

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

後で、完全に使い終わったら、単純に「mailer = nil;」とします。それを解放します。

編集: 私が提案するのは、メイン キューへのブロックを使用してリリースを行うことです。「self.mailer = nil」だけを使用すると、最終的なデリゲート メソッドが終了した後にリリースが行われ、確実にそれを使用しなくなります。

EDIT2:このクラッシュは、すべてのデバイスで常に発生するわけではありません-最終的なデリゲートメソッドを受け取ったときと、その作業が終了したときとの間の競合状態のようなものです. Apple は何らかの方法で参照を保持することについて何も述べていません - ただし、Apple 製品での一般的な慣行は、取得したオブジェクトは 1 回の runLoop を通じて「貸与中」であると想定することです。その後、参照を保持したい場合は、オブジェクトを保持します。

于 2012-08-08T17:22:43.893 に答える
3

コードにシェアキット フレームワークを実装している場合は、SHK.m に移動して変更します

        [[currentView parentViewController] dismissModalViewControllerAnimated:YES];

        [currentView  dismissModalViewControllerAnimated:YES];

これで問題は解決します。

返信ありがとうございます。

また、これらの行にコメントを付けます

SHKSwizzle([MFMailComposeViewController class], @selector(viewDidDisappear:), @selector(SHKviewDidDisappear:));
if (NSClassFromString(@"MFMessageComposeViewController") != nil) SHKSwizzle([MFMessageComposeViewController class], @selector(viewDidDisappear:), @selector(SHKviewDidDisappear:));
于 2012-08-23T06:15:48.003 に答える
2

スタックの停止はであるため、0x00000000UIKit内のコードがnil関数ポインターにジャンプしていると想定しています。ゾンビを有効にして、ゾンビオブジェクトアクセスエラーが発生するかどうかを確認します。(プロジェクトスキームを編集し、[実行/デバッグ]、[診断]タブで、[ゾンビオブジェクトを有効にする]をオンにします)

于 2012-08-13T07:35:38.873 に答える
1

ARC を使用している場合、dismiss を呼び出す前にコントローラー オブジェクトが解放されます。

スタックに割り当てられた変数以外の場所にオブジェクトを保持します。

于 2012-08-09T03:39:11.250 に答える
1

このコードを試してみてください。これはクラッシュすることなくうまく機能します..お問い合わせ方法はボタンターゲットセレクターです..

    -(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]];
}
于 2012-07-31T09:04:45.927 に答える
0

デリゲート MFMailComposeViewControllerDelegate を .h ファイルに設定しましたか。私は過去にそのような問題に直面しました。そして、エラーは非常に軽微でした。.h ファイルのデリゲートを確認してください。

于 2012-08-13T11:11:22.470 に答える