Design Pattern - Objective-C - MVC Model View Controller

design-patterns, model, model-view-controller, objective-c

Solution

Simply: `UIViewController` is not your view, it's your controller

Think of the `UIViewController` as a puppeteer and the `UIView` as the puppet.

- `UIViewController` controls WHAT is displayed on the UIView

- `UIView`'s main purpose is to contain subviews.

- `NSObject` can be used by any class, but should be used by the `UIViewController`.

Admittedly, I understood it much better after completing codeschool's tutorial http://www.codeschool.com/courses/try-ios. I highly recommend this simple hands-on approach.

Let's break it down:

Note: Here we utilize `@property` declarations instead. These will save you from writing your own setter and getter methods. (unless you need to override them for custom functionality)

NSObject (model):

//MyModelObject.h
#import <Foundation/Foundation.h>

@interface MyModelObject : NSObject

@property (nonatomic) int count; 

@end

UIView (view):

//MyView.h
#import <UIKit/UIKit.h>

@interface MyView : UIView

// holds it's own subviews
@property (strong, nonatomic) UIView *anotherView;
@property (strong, nonatomic) UIImageView *myImageView;

@end

UIViewController (controller, it all comes together here!):

//MyViewController.h
#import <Foundation/Foundation.h>

#import "MyView.h"  // your custom view
#import "MyModel.h" // your custom model

@interface MyViewController : UIViewController

@property (strong, nonatomic) MyView *myView 
// see how the view is "owned" by the view controller?

@end



//MyViewController.m

@implementation MyViewController 

@synthesize myView;


- (void) someMethod {

    [myView doSomething]; 

}

@end

Problem

Hi I already read tutorials around the web on MVC and already read the topics on here. I think i got the concept of the MVC but i'm not sure of its implementation. I've tried to apply it to a simple program, a window that have a label and a button. The button increase a counter and the label shows the value of it. I tried in 2 different ways. In the first case ( the example works ) i melt the View and the Controller. As i said, the example works, but i want you guys to tell me if it's a correct implementation for MVC or it's not following the right design. The second example has Model View and Controller as 3 separated class, but the example doesnt work because the V and the C import itself, so i would love you guys to tell me where i'm doing wrong. first version: model, view-controller ``` //Model.h #import <Foundation/Foundation.h> @interface Model : NSObject { int _counter; } -(void)setCounter:(int)valueCounter; -(int)getCounter; -(void)increaseCounter; @end //Model.m #import "Model.h" @implementation Model {} -(void)setCounter:(int)valueCounter { _counter = valueCounter; } -(int)getCounter { return _counter; } -(void)increaseCounter{ _counter ++; } @end //ViewController.h #import <UIKit/UIKit.h> #import "Model.h" @interface ViewController : UIViewController { IBOutlet UIButton *_button; IBOutlet UILabel *_label; Model *myModel; } -(IBAction)send:(id)sender; @end //ViewController.m #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; myModel = [[Model alloc]init]; _label.text = [NSString stringWithFormat:@"%d",[myModel getCounter]]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } - (IBAction)send:(id)sender{ [myModel increaseCounter]; _label.text = [NSString stringWithFormat:@"%d",[myModel getCounter]]; } @end ``` Is this way a correct Pattern for MVC ? The code works, but before i start more complex apps i want to make sure i code it in a good way. This is how i would do this app, my way of MVC. is it bad? good? how to change or fix it? Second Version: Model, View, Controller separated ----> This is the Model ``` //Model.h #import <Foundation/Foundation.h> @interface Model : NSObject { int _count; } -(void)setCount:(int)value; -(int)getCount; -(void)increaseCount; @end //Model.m #import "Model.h" @implementation Model -(void)setCount:(int)value { _count = value; } -(int)getCount { return _count; } -(void)increaseCount { _count = _count++; } @end ``` ----> This is the View ``` //View.h #import <UIKit/UIKit.h> #import "Controller.h" @interface ViewController : UIViewController{ IBOutlet UILabel *label; IBOutlet UIButton *button; Controller *myController; } @end //View.m #import "ViewController.h" #import "Controller.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; myController = [[Controller alloc]init]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } -(IBAction)pressButton:(id)sender{ label.text = [NSString stringWithFormat:@"%d",[myController actionIncrease]]; } @end ``` ----> This is the Controller ``` //Controller.m #import <Foundation/Foundation.h> @class "Model.h" @class "ViewController.h" @interface Controller : NSObject { Model *_mymodel; UIViewController *_myviewController; } -(int)actionIncrease; @end //Controller.m #import "Controller.h" #import "Model.h" @implementation Controller -(id)init{ _mymodel = [[Model alloc]init]; } -(int)actionIncrease { [_mymodel increaseCount]; return [_mymodel getCount]; } @end ``` this version doesn't work because the classes view and controller import each other and the compiler gives me a warning

Original source