解雇MFMailComposeViewController会导致EXC_BAD_ACCESS

时间:2010-11-01 00:29:04

标签: iphone crash email-integration

我正在显示MFMailComposeViewController,如下所示:

- (IBAction) contactUs: (id) sender {
    [Tracker trackContactUsPressed: [MFMailComposeViewController canSendMail]];

    if ([MFMailComposeViewController canSendMail] == NO) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle: @"Email Error"
                                                        message: @"Email has not been configured on this device.  Please send us an email at\nFOO@BAR.com"
                                                       delegate: self
                                              cancelButtonTitle: @"OK"
                                              otherButtonTitles: nil];
        [alert show];
        [alert release];
    } else {

        MFMailComposeViewController *controller = [[[MFMailComposeViewController alloc] init] autorelease];

        [controller setSubject:@"Comments about FOO"];            

        [controller setToRecipients: [NSArray arrayWithObject: @"FOO@BAR.com"]];
        [controller setMailComposeDelegate: self];

        [[self parentViewController] presentModalViewController:controller animated:YES];
    }
}

然后我的代表看起来像这样:

- (void) mailComposeController: (MFMailComposeViewController *) controller didFinishWithResult: (MFMailComposeResult) result error: (NSError *) error {
    [[self parentViewController] dismissModalViewControllerAnimated: YES];
}

但是一旦调用了委托,并且视图消失,我就会得到一个EXC_BAD_ACCESS。回溯说明了这一点:

#0  0x00000000 in ?? ()
#1  0x0065a2d9 in -[UIWindowController transitionViewDidComplete:fromView:toView:] ()
#2  0x0044a905 in -[UITransitionView notifyDidCompleteTransition:] ()
#3  0x003f1499 in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] ()
#4  0x003f132b in -[UIViewAnimationState animationDidStop:finished:] ()
#5  0x02631db0 in run_animation_callbacks ()
#6  0x02631c6f in CA::timer_callback ()
#7  0x0284bf73 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ ()
#8  0x0284d5b4 in __CFRunLoopDoTimer ()
#9  0x027a9dd9 in __CFRunLoopRun ()
#10 0x027a9350 in CFRunLoopRunSpecific ()
#11 0x027a9271 in CFRunLoopRunInMode ()
#12 0x0305500c in GSEventRunModal ()
#13 0x030550d1 in GSEventRun ()
#14 0x003cfaf2 in UIApplicationMain ()
#15 0x000023c5 in main (argc=1, argv=0xbfffefcc) at main.m:14

我似乎无法弄清楚出了什么问题。据我所知,这之前使用的是我们使用的3.x SDK(我们发布了它和所有内容!)。现在使用新的SDK(4.1)似乎失败了。我不确定这是否相关。

有谁知道什么是错的?

4 个答案:

答案 0 :(得分:8)

我发现了问题。

我们正在使用一个名为ShareKit的库来进行Twitter和Facebook集成。由于我们已经拥有自己的电子邮件表单,因此我们不需要ShareKit来处理它,因此我们删除了ShareKit的电子邮件处理文件。

一切都很好,除了在初始化时,ShareKit这样做:

SHKSwizzle([MFMailComposeViewController class], @selector(viewDidDisappear:), @selector(SHKviewDidDisappear:)); 

SHKSwizzle基本上用SHKviewDidDisappear取代了MFMailComposerViewController的viewDidDisappear:方法:(不要问我为什么......我觉得这很可怕)。

无论如何,事实证明SHKviewDidDisappear是在ShareKit的邮件处理程序中,所以删除文件是如何使代码跳转到超空间并崩溃的可怕程度。再次恢复该文件可以解决问题。

呃。

感谢大家的帮助!

答案 1 :(得分:1)

只是预感,但对我来说看起来很奇怪的是:

[[self parentViewController] presentModalViewController:controller animated:YES];

[[self parentViewController] dismissModalViewControllerAnimated: YES];

是的,我不知道你的视图控制器的安排,但直接引用[self parentViewController]是不是有点不寻常?你是三个视图控制器(调用者,父视图和模态视图)的重要耦合;这会阻止代码/视图控制器的可重用性(例如,如果您想在应用程序的其他位置的不同视图层次结构中重用相同的视图控制器)。

我可以想象你想要这样做的唯一原因是父是一个UINavigationController / UITabBarController,因为这是顶视图,你希望那个视图控制器呈现模态。

在这种情况下,我使用:

[[self navigationController] presentModalViewController:controller animated:YES]

或者更好的是,在Tab Bar情况下,我让我的根视图控制器注册一个监听通知的观察者,然后从根视图控制器启动所有模态。

我可以获得有关您的视图堆栈的更多详细信息吗?此外,你能尝试一次只是呼唤“自我”而不是父母,看看会发生什么?

答案 2 :(得分:0)

它可能会从你身下自动释放出来。我也看到过UIDocumentInteractionController也会发生这种情况。最好的解决方案可能是将MFMailComposeViewController保留在实例变量中,然后在didFinishWithResult中释放它。

答案 3 :(得分:0)

如果你想解雇邮件编辑器,最好的方法就是这样做

- (void) mailComposeController: (MFMailComposeViewController *) controller didFinishWithResult: (MFMailComposeResult) result error: (NSError *) error 
{
  [controller dismissModalViewControllerAnimated: YES];
}

这样你就不必担心控制器或其父或任何东西

还有提出作曲家, 而不是使用

 [[self parentViewController] presentModalViewController:controller animated:YES];

尝试使用

 [self presentModalViewController:controller animated:YES];