views:

107

answers:

2

Need some best practice advice here...

Navigation based application. Root view is a UITableView where user can drill down to a detail UIViewController (call it VC1). User wants to initiate some task but it may require additional info before it can proceed. If so then VC1 allocs & presents modal VC2 using the "flip" transition holding a strong reference to VC2 in a property.

All fairly standard. Here's where I'm running into trouble. Once user fills out required info in VC2 the app can either continue on to a MFMailComposeViewController or flip back to VC1. If they continue to MailCompose then when that dismisses it should return to VC1.

VC2 has a weak reference to VC1 and the problem arrises when VC2 tries to dismiss itself and present MFMailComposeViewController:

[self dismissModalViewControllerAnimated:YES];  
[VC1 performSelector:@selector(showMailModalView) withObject:nil afterDelay:0.2];

I get a EXC_BAD_ACCESS on VC1 because, apparently, my weak reference to VC1 has already been dealloc'd even though VC1 has strong reference to VC2!?!

So my question is...how should this be handled? Would the delegate pattern be better? How would that be triggered?

Note: VC1 is quite large and VC2 isn't often needed so I'm trying to keep VC2 as separate as possible from VC1 (including its own NIB).

A: 

I've run into the same problem and I'm trying to recall how I fixed it.

You might try calling:

[self.parentViewController dismissModalViewControllerAnimated:YES]

Or could you have your showMailModalView method handle dismissing the current modal view controller before showing the mail composer?

Frank Schmitt
A: 

VC2 has a weak reference to VC1 and the problem arrises when VC2 tries to dismiss itself and present MFMailComposeViewController:

What you have is a circular dependency, since VC1 knows about VC2 and then you let VC2 know about VC1. And When you have circular dependencies, you get all sorts of problems.

You should be using the delegate pattern here. When VC1 presents VC2, it should make itself VC2's delegate. When VC2 is done and wants to dismiss itself, it should let the delegate take care of that operation. In other words, the thing that shows VC2 should be the thing that dismisses VC2. VC2 should be implemented in such a way that it shouldn't know what presented it, only that what presented it will be in charge of dismissing it.

Two similar answers I've given recently:

http://stackoverflow.com/questions/2504478/pop-up-modal-with-uitableview-on-iphone/2504556#2504556

http://stackoverflow.com/questions/2506927/call-method-in-a-subclass-of-uiview/2510134#2510134

Shaggy Frog