0

我之前过一个关于同一问题的问题,解决方案有效,但它不是兼容 iOS 4.3 的解决方案,我认为我的设计不正确。

现在,当我按下按钮时,我想在我的 RootView(Controller) 顶部将 MFMailComposeView(Controller) 显示为模式视图。而不是让它成为委托,我想做一个简单的 NSObject 来实现协议。谁也能够在 RootViewController 中显示 MFMailComposeView(Controller)。

我正在尝试这种设计/解决方案,它会给我带来内存分配/访问问题。

RootViewController.m:

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

发送邮件控制器.h

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

@property (retain, nonatomic) UIViewController* parentViewController;

@end

发送邮件控制器.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)的委托属性有关吗?

4

1 回答 1

0

问题是您创建实例SendMailController并尝试显示作曲家视图,然后释放SendMailController. 这会导致它被释放。看起来它可以工作,因为作曲家视图在屏幕上 - 这是因为它已被presentModalViewController调用保留。

要修复,您需要保留您的实例SendMailController并在作曲家被解雇时释放它。

正确的方法(如果你使用 ARC 并且你应该使用 ARC 是必需的)是提供一个委托回调来告诉所有者它已经完成 - 如果它所做的只是包装作曲家,那么这种方法会使类变得毫无意义。

作弊方式(仅在不使用 ARC 时有效,并且您需要非常小心)是让您的对象在呈现作曲家时保留自己,并在作曲家被解雇时释放自己。

根本问题是您的根视图控制器包含所有逻辑,您应该考虑使用子视图控制器(如果单个屏幕包含所有 UI)。通常,您的根视图应该是简单的类(如选项的主列表),它呈现的视图会更复杂(详细视图)。您需要确保适当的类负责 UI 的每个屏幕。

于 2013-05-11T06:45:49.080 回答