美文网首页设计模式
iOS:常见架构

iOS:常见架构

作者: 春暖花已开 | 来源:发表于2020-08-14 10:07 被阅读0次

    常见的架构有 MVCMVPMVVM。下面分别用代码做下演示。

    MVC
    #import "ViewController.h"
    
    #pragma mark - Model
    @interface MZPerson : NSObject
    
    @property (copy, nonatomic) NSString *name;
    @property (copy, nonatomic) NSString *image;
    
    @end
    
    @implementation MZPerson
    @end
    
    
    #pragma mark - View
    
    @class MZView;
    @protocol MZClickDelegate <NSObject>
    @optional
    - (void)viewDidClicked:(MZView *)view;
    
    @end
    
    @interface MZView : UIView
    
    @property (nonatomic, strong) MZPerson *model;
    @property (nonatomic, weak) id<MZClickDelegate> delegate;
    
    @end
    
    @interface MZView ()
    
    //特点: 将View内部的细节封装起来了,外界不知道View内部的具体实现
    @property (nonatomic, strong) UIImageView *iconView;
    @property (nonatomic, strong) UILabel *nameLabel;
    
    @end
    
    @implementation MZView
    
    - (instancetype)initWithFrame:(CGRect)frame {
        if (self = [super initWithFrame:frame]) {
            UIImageView *iconView = [[UIImageView alloc] init];
            iconView.frame = CGRectMake(0, 0, 100, 100);
            [self addSubview:iconView];
            _iconView = iconView;
            
            UILabel *nameLabel = [[UILabel alloc] init];
            nameLabel.frame = CGRectMake(0, 100, 100, 30);
            nameLabel.textAlignment = NSTextAlignmentCenter;
            [self addSubview:nameLabel];
            _nameLabel = nameLabel;
        }
        return self;
    }
    
    - (void)setModel:(MZPerson *)model {
        _model = model;
        
        self.iconView.image = [UIImage imageNamed:model.image];
        self.nameLabel.text = model.name;
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        if ([self.delegate respondsToSelector:@selector(viewDidClicked:)]) {
            [self.delegate viewDidClicked:self];
        }
    }
    
    @end
    
    #pragma mark - Controller
    
    @interface ViewController ()<MZClickDelegate>
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //view
        MZView *view = [[MZView alloc] initWithFrame:CGRectMake(100, 100, 100, 150)];
        view.delegate = self;
        [self.view addSubview:view];
        
        //model
        MZPerson *model = [[MZPerson alloc] init];
        model.name = @"路飞";
        model.image = @"lufei";
        
        //设置数据到view上
        view.model = model;
    }
    
    //代理方法
    - (void)viewDidClicked:(MZView *)view {
        NSLog(@"控制器接收到view的点击");
    }
    
    @end
    

    MVP

    MVP与MVC的区别在于:MVP将MVC中控制器的逻辑抽离出来放到presenter里(每一个大的逻辑都可以抽成一个presenter)。

    #import "ViewController.h"
    
    #pragma mark - Model
    @interface MZPerson : NSObject
    
    @property (copy, nonatomic) NSString *name;
    @property (copy, nonatomic) NSString *image;
    
    @end
    
    @implementation MZPerson
    @end
    
    
    #pragma mark - View
    
    @class MZView;
    @protocol MZClickDelegate <NSObject>
    @optional
    - (void)viewDidClicked:(MZView *)view;
    
    @end
    
    @interface MZView : UIView
    
    @property (nonatomic, strong) MZPerson *model;
    @property (nonatomic, weak) id<MZClickDelegate> delegate;
    
    @end
    
    @interface MZView ()
    
    //特点: 将View内部的细节封装起来了,外界不知道View内部的具体实现
    @property (nonatomic, strong) UIImageView *iconView;
    @property (nonatomic, strong) UILabel *nameLabel;
    
    @end
    
    @implementation MZView
    
    - (instancetype)initWithFrame:(CGRect)frame {
        if (self = [super initWithFrame:frame]) {
            UIImageView *iconView = [[UIImageView alloc] init];
            iconView.frame = CGRectMake(0, 0, 100, 100);
            [self addSubview:iconView];
            _iconView = iconView;
            
            UILabel *nameLabel = [[UILabel alloc] init];
            nameLabel.frame = CGRectMake(0, 100, 100, 30);
            nameLabel.textAlignment = NSTextAlignmentCenter;
            [self addSubview:nameLabel];
            _nameLabel = nameLabel;
        }
        return self;
    }
    
    - (void)setModel:(MZPerson *)model {
        _model = model;
        
        self.iconView.image = [UIImage imageNamed:model.image];
        self.nameLabel.text = model.name;
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        if ([self.delegate respondsToSelector:@selector(viewDidClicked:)]) {
            [self.delegate viewDidClicked:self];
        }
    }
    
    @end
    
    
    #pragma mark - Presenter
    
    @interface MZPresenter : NSObject<MZClickDelegate>
    
    - (instancetype)initWithController:(UIViewController *)viewController;
    
    @end
    
    @implementation MZPresenter
    
    - (instancetype)initWithController:(UIViewController *)viewController {
        if (self = [super init]) {
            
            //view
            MZView *view = [[MZView alloc] initWithFrame:CGRectMake(100, 100, 100, 150)];
            view.delegate = self;
            [viewController.view addSubview:view];
            
            //model
            MZPerson *model = [[MZPerson alloc] init];
            model.name = @"路飞";
            model.image = @"lufei";
            
            //设置数据到view上
            view.model = model;
        }
        return self;
    }
    
    //代理方法
    - (void)viewDidClicked:(MZView *)view {
        NSLog(@"控制器接收到view的点击");
    }
    
    @end
    
    
    #pragma mark - Controller
    
    @interface ViewController ()
    
    @property (strong, nonatomic) MZPresenter *presenter;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.presenter = [[MZPresenter alloc] initWithController:self];
    }
    
    @end
    

    MVVM
    #import "ViewController.h"
    #import "NSObject+FBKVOController.h"
    
    #pragma mark - Model
    @interface MZPerson : NSObject
    
    @property (copy, nonatomic) NSString *name;
    @property (copy, nonatomic) NSString *image;
    
    @end
    
    @implementation MZPerson
    @end
    
    
    #pragma mark - View
    
    @class MZView, MZViewModel;
    @protocol MZClickDelegate <NSObject>
    @optional
    - (void)viewDidClicked:(MZView *)view;
    
    @end
    
    @interface MZView : UIView
    
    @property (nonatomic, strong) MZViewModel *viewModel;
    @property (nonatomic, weak) id<MZClickDelegate> delegate;
    
    @end
    
    @interface MZView ()
    
    //特点: 将View内部的细节封装起来了,外界不知道View内部的具体实现
    @property (nonatomic, strong) UIImageView *iconView;
    @property (nonatomic, strong) UILabel *nameLabel;
    
    @end
    
    @implementation MZView
    
    - (instancetype)initWithFrame:(CGRect)frame {
        if (self = [super initWithFrame:frame]) {
            UIImageView *iconView = [[UIImageView alloc] init];
            iconView.frame = CGRectMake(0, 0, 100, 100);
            [self addSubview:iconView];
            _iconView = iconView;
            
            UILabel *nameLabel = [[UILabel alloc] init];
            nameLabel.frame = CGRectMake(0, 100, 100, 30);
            nameLabel.textAlignment = NSTextAlignmentCenter;
            [self addSubview:nameLabel];
            _nameLabel = nameLabel;
        }
        return self;
    }
    
    - (void)setViewModel:(MZViewModel *)viewModel {
        _viewModel = viewModel;
        
        __weak typeof(self) waekSelf = self;
        [self.KVOController observe:viewModel keyPath:@"name" options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, id  _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) {
            waekSelf.nameLabel.text = change[NSKeyValueChangeNewKey];
        }];
        
        [self.KVOController observe:viewModel keyPath:@"image" options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, id  _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) {
            waekSelf.iconView.image = [UIImage imageNamed:change[NSKeyValueChangeNewKey]];
        }];
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        if ([self.delegate respondsToSelector:@selector(viewDidClicked:)]) {
            [self.delegate viewDidClicked:self];
        }
    }
    
    @end
    
    
    #pragma mark - Presenter
    
    @interface MZViewModel : NSObject
    
    - (instancetype)initWithController:(UIViewController *)viewController;
    
    @end
    
    @interface MZViewModel ()<MZClickDelegate>
    
    @property (weak, nonatomic) UIViewController *controller;
    @property (copy, nonatomic) NSString *name;
    @property (copy, nonatomic) NSString *image;
    
    @end
    
    @implementation MZViewModel
    
    - (instancetype)initWithController:(UIViewController *)viewController {
        if (self = [super init]) {
            
            self.controller = viewController;
            
            //view
            MZView *view = [[MZView alloc] initWithFrame:CGRectMake(100, 100, 100, 150)];
            view.delegate = self;
            view.viewModel = self;
            [viewController.view addSubview:view];
            
            //model
            MZPerson *model = [[MZPerson alloc] init];
            model.name = @"路飞";
            model.image = @"lufei";
            
            // 设置数据
            self.name = model.name;
            self.image = model.image;
        }
        return self;
    }
    
    //代理方法
    - (void)viewDidClicked:(MZView *)view {
        NSLog(@"控制器接收到view的点击");
    }
    
    @end
    
    
    #pragma mark - Controller
    
    @interface ViewController ()
    
    @property (strong, nonatomic) MZViewModel *viewModel;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.viewModel = [[MZViewModel alloc] initWithController:self];
    }
    
    @end
    

    相关文章

      网友评论

        本文标题:iOS:常见架构

        本文链接:https://www.haomeiwen.com/subject/fospdktx.html