views:

146

answers:

2

I'm using the Three20 TTMessageController in my app. I've figured out how to use it, adding on a bunch of other stuff (including TTMessageControllerDelegate methods and ABPeoplePickerNavigationControllerDelegate methods). It works great for me, after a bit of a struggle to figure it out.

The trouble I'm having now is a design issue: I want to use it identically in two different places, including with the same delegate methods. My current approach is that I've put all the code into a single class inheriting from NSObject, called ComposerProxy, and I'm just having the two controllers that use it use the proxy, like so:

ComposerProxy *proxy = [[ComposerProxy alloc] initWithController:this];
[proxy go];

The go method constructs the TTMessageController, configures it, adds it to a UINavigationController, and presents it:

[self.controller presentModalViewController: navController animated: YES];

This works great, as I have all my code nicely encapsulated in ComposerProxy and I need only the above two lines anywhere I want to use it.

The downside, though, is that I can't dealloc the proxy variable without getting crashes. I can't autorelease it, either: same problem.

So I'm wondering if my proxy approach is a poor one. How does one normally encapsulate a bunch of behaviors like this without requiring a lot of duplicate code in the classes that use it? Do I need to add a delegate class to my ComposerProxy and make the controller responsible for dismissing the modal view controller in a hypothetical composerDidFinish method or some such?

Many TIA!

+1  A: 

From what I see above, the crashes don't necessarily indicate a poor design - chances are it's crashing on a memory management issue. Maybe controller is over-released, hard to say - what kind of crash are you getting?

While the current design seems fine, an alternative would be to create a category on UIViewController. The category would add (to UIViewController subclasses that import the category) all the code necessary for presenting a modal TTMessageController without requiring you to duplicate or use inheritance.

@interface UIViewController ( Composer )
// categories can't add instance vars, so return the new controller if you need to store it...
- (TTMessageController *)presentMessageController;
@end

@implementation UIViewController ( Composer )
- (TTMessageController *)presentMessageController {
    // contents of ComposerProxy#go except referring to 'self' instead of 'self.controller'
}
@end
dbarker
Ah, I hadn't thought to add a category. That's a very good idea (I've done it for other stuff, just not controllers). I suppose the category adds whatever delegates it implements as well.The memory issue, I think, is because the calling class doesn't keep the proxy object in an instance attribute, so if it releases it, it doesn't work properly because there are no references to it. Been pondering if there's a way to fix that, but going with a category is probably a better idea anyway. Thanks!
Theory
A: 

Hi,

I am struggling to get the ABPeoplePickerNavigationControllerDelegate + TTMessageController working together. Like you i am looking for something i can call from a number of places, is this something you would mind sharing with me or able to point me in the right direction.

Thanks, Mike

Mike Barlow