どこか:
if([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *email_vc = [[MFMailComposeViewController alloc] init];
email_vc.mailComposeDelegate = self;
[email_vc setSubject:subject];
[email_vc setMessageBody:message isHTML:FALSE];
[email_vc setToRecipients:recipients];
[self presentModalViewController:email_vc animated:FALSE];
[[UIApplication sharedApplication] setStatusBarHidden:TRUE];
[email_vc release];
}
else
...
何処か別の場所:
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(@"Cancelled");
break;
case MFMailComposeResultSaved:
NSLog(@"Saved");
break;
case MFMailComposeResultSent:
NSLog(@"Sent");
break;
case MFMailComposeResultFailed:
NSLog(@"Compose result failed");
break;
default:
NSLog(@"Default: Cancelled");
break;
}
// This ugly thing is required because dismissModalViewControllerAnimated causes a crash
// if called right away when "Cancel" is touched.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC), dispatch_get_current_queue(), ^
{
[self dismissModalViewControllerAnimated:FALSE];
});
}
その醜い「dispatch_after」ブロックは、クラッシュせずにこれを機能させる唯一の方法です。
コンテキストは、電子メール作成ビュー コントローラーで「送信」以外のものに触れると、クラッシュが発生するということです。この醜いバンドエイドに頼らずにこれに対処する方法はありますか? バンドエイドに関する私の理論は、「キャンセル」をタッチすると、ユーザーが本当にキャンセルしたいことを確認するために中間ビューが表示されるというものです。[self dismissModalViewControllerAnimated:FALSE];
ビューを順序どおりに却下しようとしているのか、それともその効果があるのか 疑問に思っています。わずかな遅延を挿入することで、メール作成ビューが消えるように求められる前にクリーンアップする時間があると理論付けています。
別の質問で遅延が使用されているのを見ました。ただし、著者は詳細には触れませんでした。
iPad の MFMailComposeViewController でクラッシュする
編集 1: クラッシュ ログの追加
Incident Identifier: ****************
CrashReporter Key: *****************
Hardware Model: iPhone4,1
Process: ************* [9038]
Path: /var/mobile/Applications/*********************
Identifier: ***********************
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2012-07-20 11:25:53.704 -0700
OS Version: iPhone OS 5.0.1 (9A405)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0xa003853a
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x316b9fbc 0x316b6000 + 16316
1 UIKit 0x350caa9e 0x34f8e000 + 1297054
2 UIKit 0x34fa6814 0x34f8e000 + 100372
3 UIKit 0x34fabfb2 0x34f8e000 + 122802
4 QuartzCore 0x33354ba0 0x33329000 + 179104
5 libdispatch.dylib 0x37896f74 0x37894000 + 12148
6 CoreFoundation 0x37bac2d6 0x37b20000 + 574166
7 CoreFoundation 0x37b2f4d6 0x37b20000 + 62678
8 CoreFoundation 0x37b2f39e 0x37b20000 + 62366
9 GraphicsServices 0x376adfc6 0x376aa000 + 16326
10 UIKit 0x34fbf73c 0x34f8e000 + 202556
11 ***************** 0x00002346 main (main.m:14)
12 ***************** 0x00002304 start + 32
編集 2: 頭を悩ませた結果、これは本物の Apple のバグであることがわかりました。
MailComposer サンプル プロジェクトをダウンロードして実行しました。
http://developer.apple.com/library/ios/#samplecode/MailComposer/Introduction/Intro.html
それは正常に動作します。
次に、コードを編集して、メール作成コントローラーを表示および非表示にする際のアニメーションを削除しました。
[self presentModalViewController:picker animated:FALSE];
と
[self dismissModalViewControllerAnimated:FALSE];
案の定、「キャンセル」を使用してメール作成 UI を閉じるとクラッシュしました。
実行中のゾンビはこれをもたらしました:
-[MFMailComposeController actionSheet:didDismissWithButtonIndex:]: message sent to deallocated instance 0x7479ef0
アクションシートは、メール作成ビューコントローラーの代わりに却下メッセージを受け取ると思います。
誰かが動作を確認できたら、バグを報告します。
編集 3: バグが報告されました。
私が受け入れた回答には、この問題を引き起こしている潜在的なメカニズムがよく説明されています。また、回答コメントのやり取り中に、2 つの追加の回避策が特定されました。すべてのバンドエイドですが、現在はいくつかの選択肢があります.
まだ確認していませんが、ShareKit もこのバグの影響を受けていると思われます (メール作成ビュー コントローラーの表示がアニメーション化されていない場合)。