为什么MFMailComposeViewController返回MFMailComposeResultFailed?

我在我的应用程序面临一个奇怪的问题,我需要你的帮助!
我正在使用MFMailComposeViewController发送附件数据的电子邮件。 附件可以是PDF,CSV或XLS文件。 ZIP文件也可以添加到邮件中。

在大多数情况下,一切正常,但有时(实际上很常见),当附件是一个XLS和ZIP添加,我收到多个内存警告,composer php返回MFMailComposeResultFailed,有一个错误,根本没有帮助(只说代码错误1,“操作无法完成(MFMailComposeErrorDomain错误1.)”)。

我的问题是为什么这样做? 我假设内存警告告诉我一些pipe理不善,但我无法弄清楚什么…

这是我发送电子邮件的代码

-(void) sendMail { MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init]; [self prepareMailPicker:picker]; NSString *filePath = [self getFilePath:pType]; NSString *zipFile = [self getZipPath]; NSString *mimeType; int userPhoto = [User getCSVPhoto]; switch (pType) { case EPDF: mimeType = @"application/pdf"; userPhoto = [User getPDFPhoto]; break; case ECSV: mimeType = @"text/csv"; break; case EExcel: mimeType = @"application/vnd.ms-excel"; break; default: break; } NSData *attachmentData = [NSData dataWithContentsOfFile:filePath]; [picker addAttachmentData:attachmentData mimeType:mimeType fileName:[filePath lastPathComponent]]; if (userPhoto == 1 && shouldAddZip) { NSData *zipData = [NSData dataWithContentsOfFile:zipFile]; [picker addAttachmentData:zipData mimeType:@"application/zip" fileName:[zipFile lastPathComponent]]; } shouldAddZip = NO; [self presentModalViewController:picker animated:YES]; } -(void) prepareMailPicker:(MFMailComposeViewController*)picker { picker.mailComposeDelegate = (id<MFMailComposeViewControllerDelegate>)self; picker.navigationBar.tintColor = grayDark; [picker setSubject:[TextManager textForKey:@"EMAIL_SUBJECT"]]; NSString *email = [[User currentUser] getEmail]; if (email && ![email isEqualToString:@""]) [picker setToRecipients:[NSArray arrayWithObject:email]]; NSString *emailBody = [TextManager textForKey:@"EMAIL_TEXT"]; [picker setMessageBody:emailBody isHTML:YES]; } 

任何帮助将是懊悔!

编辑:由@matt问,这里是一个日志certificate什么都没有设置为零:

 filePath : /var/mobile/Applications/A57F5CD2-E3FE-4417-8810-D746A22CF434/Documents/iNdF_Export_2012-11-19.xls zipFile : /var/mobile/Applications/A57F5CD2-E3FE-4417-8810-D746A22CF434/Documents/iNdF_recus_2012-11-19.zip attachmentData : (NSConcreteData *) <0x1d9c3c20> 53 874 bytes zipData : (NSConcreteData *) <0x1f989100> 6 838 456 bytes 

正如你所说,考虑到你收到的内存警告,这个问题似乎很可能与内存pipe理有关。

你的代码保留了来自第一个文件attachmentData的引用计数,即使它出去获取第二个文件的zipData。 在内部,选取器可能正在复制该数据…

因此,尽可能早地释放对大数据的引用,就越有可能获得内存警告。

如果问题在于由于内存不足而无法完成附件,并且您可以通过提前发布来完成附件,那么按以下方式分解代码可能会对您有所帮助。

 - (void)sendMailPicker:(MFMailComposeViewController*)picker addAttachmentUsingMimeType:(NSString*)mimeType { NSString *filePath = [self getFilePath:pType]; NSData *attachmentData = [NSData dataWithContentsOfFile:filePath]; [picker addAttachmentData:attachmentData mimeType:mimeType fileName:[filePath lastPathComponent]]; } - (void)sendMailAddPhotoUsingPicker:(MFMailComposeViewController*)picker { NSString *zipFile = [self getZipPath]; NSData *zipData = [NSData dataWithContentsOfFile:zipFile]; [picker addAttachmentData:zipData mimeType:@"application/zip" fileName:[zipFile lastPathComponent]]; } - (void)sendMail { MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init]; [self prepareMailPicker:picker]; NSString *mimeType; int userPhoto = [User getCSVPhoto]; switch (pType) { case EPDF: mimeType = @"application/pdf"; userPhoto = [User getPDFPhoto]; break; case ECSV: mimeType = @"text/csv"; break; case EExcel: mimeType = @"application/vnd.ms-excel"; break; default: break; } [self sendMailPicker:picker addAttachmentUsingMimeType:mimeType]; if (userPhoto == 1 && shouldAddZip) { [self sendMailAddPhotoUsingPicker:picker]; } shouldAddZip = NO; [self presentModalViewController:picker animated:YES]; } 

我想这个问题与内存有关,当你在堆中创buildNSData的时候。 如果它很大,你会开始收到内存警告。 避免内存的一种方法可能是创build内存映射的NSData或NSStream,但是我不知道如何在邮件编辑器中集成NSStream。 你的附件的平均尺寸是多less?
您也可以尝试使用Allocations来分析您的应用程序,以查看应用程序的内存占用情况,可能已经太高了。

就像我之前遇到的一些问题一样。 1.请检查,使用“Reachability”类文件有互联网可用性。 2.请检查您的数据大小是否在限制范围内。 3.请检查您是否使用您的设备configuration了您的电子邮件ID。 你也可以调用[yourobj cansendmail]函数来检查是否可以发送邮件。