是的!我做到了!我不敢相信,但我解决了这个问题!这与以下内容有关:
从其他打开的模态控制器(和以上)打开一个 MFMailComposeViewController 作为模态控制器
不幸的是,我不得不再次承认,在像恶魔一样昂贵的 iPhone 5 时代,Apple 仍然强迫开发人员使用旧的、有缺陷的和不方便的代码和组件!MFMailComposeViewController 就是一个很好的例子。
但是现在让我们继续更愉快的事情。
我们有什么:
- 这个问题出现在带有 iOS 5.1 的 iPhone 和带有 iOS 6 的模拟器上。
- 核心问题是当您尝试从另一个模态控制器打开电子邮件控制器作为模态控制器时。
- [MFMailComposeViewController canSendMail ]对我完全没有影响- 它在两种方式中都不起作用(它在有或没有可用的电子邮件功能时崩溃)。
- [self dismissModalViewControllerAnimated: NO/YES ]并没有改变一般的感觉——它在两种情况下都崩溃了,但行为略有不同。
- 我试图对mailComposeDelegate使用标准方法(如'.mailComposeDelegate = self')。
- 我从两个调用电子邮件发送控制器:通用(第一级)控制器以及来自同一个应用程序的模态(第二级)控制器。
- 应用程序并不总是崩溃 -有时控制器无法自行关闭(按钮“取消”和“发送”处于活动状态,但未处理任何操作)。取决于条件(谁是父母打开了控制器,是动画还是没有出现等)。
- 是否添加了任何电子邮件收件人也没有区别。
所以,我杀死的 5 个工作小时发现的是,代表似乎在某个时候“释放”了。我可以假设,如果您将电子邮件控制器作为模态打开而不是其他模态控制器,那么(以前的模态)控制器正在被垃圾收集器或其他方式清理,并且委托也被清理(我不希望为详细挖掘再浪费几个小时,所以我会把它留给苹果的良心)。
无论如何,简而言之,我的解决方案是
将委托对象保存在具有“强”引用的某处。
就我而言,该委托的所有者是主视图控制器类(在我的情况下始终可用,因为大多数应用程序逻辑都在使用它)。那也可以是 AppDelegate 实例。
它看起来像:
@interface SharingTools : NSObject <MFMailComposeViewControllerDelegate>
@property UIViewController* currentParentController;
...
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
if (error)
{
...
}
else
{
// I pass it somewhere before calling the email controller dialog opener method,
// because it's different in case we open the email sender
// from first-level controller or second- (the modal one)
[currentParentController dismissViewControllerAnimated:YES completion:^{
if (_onResult) {
((void(^)(bool))_onResult)(result == MFMailComposeResultSent);
}
}];
}
// and of course clearing all the references etc here
currentParentController.mailComposeDelegate = nil;
currentParentController = nil;
}
-(void)sendEmail //... params here
// (possibly, including to store also currentParentController)
{
currentParentController = ... ;
[currentParentController presentViewController:
newlyCreatedEmailController animated:YES completion:nil];
}
@end
@interface MyMainViewController : UIViewController
@property SharingTools* sharing; // initialize somewhere (on viewDidLoad, for instance)
...
-(void)showSettings
{
...
[self presentModalViewController:settingsController animated:YES];
}
@end
@interface SettingsViewController : UIViewController
...
-(void)sendEmailSupport
{
// again, this is up to you where and how to have either reference
// to main controller (or any other owner of the delegate object)
// or sharing directly
[myMainViewControllerInstance.sharing sendEmail: ... parentController:self];
}
@end
坦率地说,代码有点乱,但这只是一般的想法。我希望,你会更好地管理自己的。
祝你好运,上帝保佑微软!^^