tags:

views:

130

answers:

1

I have a view controller (let's call it MainViewController) that contains a UITabBarController, where each TabBarItem connecting to its respective UIViewController-derived classes. For certain UIViewControllers, I want to pass in value at the time via MainViewController. What's the best way to do this proxy'ing?

Right now, I end up having to create a property for proxy purposes in MainViewController. But ideally, I would rather MainViewController not know the specific type of UIViewController it has to pass the value to and the specific type of value that it's passing, since the value is never used in MainViewController, I see the coupling as being unnecessary.

e.g.

Let's say tab bar item 2 connects to UIEmployeeInfoViewController class. And UIEmployeeInfoViewController is interested in an object of type called EmployeeInfo.

Here is my current solution but it's what I am trying to avoid doing in search of a better approach:


1) Somewhere where UIMainViewController is being create...

UIMainViewController *mainViewController = [[UIMainViewController alloc] initWith...];

// a property called employeeInfo is created in UIMainViewController class so it can be forwarded later
mainViewController.employeeInfo = employeeInfoObj;  

...


2) Code to make UIMainViewController pass the employeeInfo along to UIEmployeeInfoViewController when the tabbar item is tapped:

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
    if ([viewController class] == [UIEmployeeInfoViewController class])
    {
           // Need to create coupling to UIEmployeeInfoViewController class
           // and to EmployeeInfo class as well
           ((UIEmployeeInfoViewController *)viewController).employeeInfo = self.employeeInfo;
    }


    return YES;
}
A: 

Okay, first off, do not prefix your classes with the characters UI. It is reserved for UIKit. Objective-C has no namespaces, so uses well known prefixes (especially ones used by Apple) is a bad idea.

There are a couple of options here.

You can create a UIViewController subclass that all of your classes derive from that and takes some shared controller object (like UIMainViewController *) at the time of creation and have those classes query the shared object instead of the other way around. That reverses the nature of dependency.

@interface CoreViewController : UIViewController {
  MainViewController *mainViewController;
}

@property (nonatomic, retain, readonly) MainViewController *mainViewController;

@end 

@implementation CoreViewController

@synthesize mainViewController;

- (id) initWithMainViewController:(MainViewController *)mainVC {
  self = [super initWithNibName:nil bundle:nil];

  if (self) {
    mainViewController = [mainVC retain];
  }

  return self;
}

- (void) dealloc {
  [mainViewController retain];

  [super dealloc];
}

@end

And then just get your data by pulling it from the self.mainViewController. Depending on the nature of your app that might be a pretty strong coupling another option is to just shove it all that kind of shared state into a singleton everything talks to. That has the benefit that you can have all of your objects register KVO observers on the singleton watch for changes instead of explicitly checking it.

Louis Gerbarg
Thanks for pointing out the use of using UI namespace. Don't use it in my code, was just using a quick name. Ideally, I would like them to not know about each other at all so they can be freely plugged and played. It just so happens that there is a dependency in this use case but I don't want any coupling to be developed due to that. That is, if I can do away with MainViewController knowing CoreViewController and vice versa, then I want to do that.
Boon
Come to think of it, perhaps what I should do is go with the regular Delegate pattern, whereby MainViewController will declare itself to implement CoreViewController's delegate and CoreViewController will get the data via the delegate, which in this case is MainViewController.
Boon