0

以前に同じ問題について質問したことがあり、解決策は機能しましたが、互換性のある iOS 4.3 ソリューションではなく、私の設計は適切ではないと思いました。

ボタンを押したときに、MFMailComposeView(Controller) を RootView(Controller) の上にモーダル ビューとして表示したいと考えています。そして、デリゲートにする代わりに、プロトコルを実装する単純な NSObject を作成したいと考えています。RootViewController で MFMailComposeView(Controller) を表示できるのは誰ですか。

この設計/解決策を試しているところ、メモリ割り当て/アクセスの問題が発生します。

RootViewController.m:

- (IBAction)tapExportButton:(id)sender
{
    SendMailController *sendMailController = [[SendMailController alloc]initWithParentViewController:self];
    [sendMailController openMailDialog];
    [sendMailController release];
}

SendMailController.h

@interface SendMailController : NSObject <MFMailComposeViewControllerDelegate>
- (id)initWithParentViewController:(UIViewController *)parentViewController;
- (void)openMailDialog;

@property (retain, nonatomic) UIViewController* parentViewController;

@end

SendMailController.m

#import "SendMailViewController.h"

@implementation SendMailController

@synthesize parentViewController = _parentViewController;

- (id)initWithParentViewController:(UIViewController *)parentViewController
{
    if (self=[super init]) {
        self.parentViewController = parentViewController;
    }
    return self;
}

- (void) dealloc
{
    self.parentViewController = nil;
    [super dealloc];
}

- (void)openMailDialog
{
    if ([MFMailComposeViewController canSendMail])
    {
        MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
        mailer.mailComposeDelegate = self;
        ...
        mailer.modalPresentationStyle = UIModalPresentationPageSheet;
        [self.parentViewController presentModalViewController:mailer animated:YES];
        [mailer release];
    }
}


- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
    switch (result)
    ...
    // Remove the mail view
    [controller.parentViewController dismissModalViewControllerAnimated:YES];
}

@end

委任メソッドにブレークポイントを設定すると、その前に既にクラッシュします。メーラー(MFMailComposeViewController)のdelegateプロパティとは何か?

4

1 に答える 1

0

問題は、 のインスタンスを作成しSendMailControllerてコンポーザー ビューを表示しようとした後、SendMailController. これにより、割り当てが解除されます。コンポーザ ビューが画面上にあるため、機能しているように見えます。これは、presentModalViewController呼び出しによって保持されているためです。

修正するには、インスタンスを保持SendMailControllerし、コンポーザーが閉じられたときにそれを解放する必要があります。

それを行う正しい方法 (および ARC を使用する場合に必要であり、ARC を使用する必要があります) は、所有者に終了したことを伝えるデリゲート コールバックを提供することです。

不正行為の方法 (ARC を使用していない場合にのみ機能し、非常に注意する必要があります) は、オブジェクトがコンポーザーを提示するときにそれ自体を保持し、コンポーザーが閉じられるときにそれ自体を解放することです。

根底にある問題は、すべてのロジックを含むルート ビュー コントローラーです。子ビュー コントローラーの使用を検討する必要があります (1 つの画面にすべての UI が含まれている場合)。ただし、通常、ルート ビューは単純なクラス (オプションのマスター リストなど) である必要があり、表示されるビューはより複雑になります (詳細ビュー)。適切なクラスが UI の各画面の責任を所有していることを確認する必要があります。

于 2013-05-11T06:45:49.080 に答える