Samui
Samui

Reputation: 1384

Objective-C: MVC with one model and various viewcontrollers

I have a RootViewController (navigation based application) that ask a model (brain.h/m) to perform and retrieve some information. Obviously I've instantiated a model variable first.

This is the RootViewController.h interface:

#import <UIKit/UIKit.h>
#import "Brain.h"


@interface RootViewController : UITableViewController 
{
 Brain *cerebro;
}

@property (nonatomic, retain) Brain *cerebro;

@end

I've added a second viewcontroller to control a detailed view that is displayed when the user taps a row in the tableview of the first viewcontroller:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

 /*
  <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
  [self.navigationController pushViewController:detailViewController animated:YES];
  [detailViewController release];
  */

How can I reference and ask the model that the first viewcontroller had instantiated without instantiate it again in the second viewcontroller?

Upvotes: 0

Views: 427

Answers (3)

PofMagicfingers
PofMagicfingers

Reputation: 215

You can try adding this reference directly on AppDelegate to make it like a fake global var.

ie :

in the AppDelegate interface :

Brain *cerebro;

@property (nonatomic, retain) Brain *cerebro;

And anywhere in the code :

[(MyAppDelegate *)[[UIApplication sharedApplication] delegate] cerebro]

should work well...


If you use many times, and only one Brain think about implementing a singleton

If you use many Brain it might be a good idea to implement a singleton BrainManager you could use like this :

Brain *cerebro = [[Brain alloc] init...]
[[BrainManager sharedManager] addBrain:cerebro withIdentifier:@"cerebro"];

And somewhere else :

[SomeThing DoTaskWithBrain:[[BrainManager sharedManager] brainWithIdentifier:@"cerebro"]];

Upvotes: 0

outis
outis

Reputation: 77400

You can take a page from the connectivity rules of capabilities programming and have the root controller introduce or endow the Brain to the subordinate controller.

Introduction:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  <#DetailViewController#> *detailViewController 
      = [[<#DetailViewController#> alloc] 
              initWithNibName:@"<#Nib name#>" 
                       bundle:nil];
  // introduce the Brain
  detailViewController.brain = ref.to.rootController.brain;
  // ...
  // Pass the selected object to the new view controller.
  [self.navigationController pushViewController:detailViewController animated:YES];
  [detailViewController release];

Endowment:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  <#DetailViewController#> *detailViewController 
      = [[<#DetailViewController#> alloc] 
              initWithNibName:@"<#Nib name#>" 
                       bundle:nil 
                        brain:ref.to.rootController.brain];
  // ...
  // Pass the selected object to the new view controller.
  [self.navigationController pushViewController:detailViewController animated:YES];
  [detailViewController release];

Upvotes: 1

Stephan
Stephan

Reputation: 4263

I am not sure I understood your question .... but i try :)

Why you not just define a property in your second controller for the model class(es) and set it e.g. during the viewDidLoad of your first controller.

Or you have a reference in all your controllers to you data model classes. A good place for data model management is the AppDelegate.

If you create a application based on the "Split View based Application" template of Xcode you get a good example.

Upvotes: 0

Related Questions