中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

iOS中的MVP模式初探

2018-07-20    來源:編程學(xué)習(xí)網(wǎng)

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

以前在項目中都寫的是MVC模式, 由于現(xiàn)在在項目中要學(xué)習(xí)MVP模式, 所以找了一個Demo研究了一下. 就簡單說說自己的看法吧.

先說一下MVC模式, 示意圖如下:

MVC模式示意圖

  • 模型拿到數(shù)據(jù), 可能是數(shù)據(jù)庫或者網(wǎng)絡(luò)數(shù)據(jù)

最簡單的比方, 我們拿到一個模型數(shù)組了之后, 這個就相當(dāng)于是一個數(shù)據(jù)源.

  • 將數(shù)據(jù)傳遞給控制器, 控制器經(jīng)過簡單地加工

數(shù)據(jù)源經(jīng)過簡單地處理加工, 比如在tableView中, 我們可能會使用數(shù)據(jù)源方法, 將模型數(shù)組中的元素取出來, 傳遞給View層, 比如cell

  • 將加工后的數(shù)據(jù)展示出來

cell展示模型中的數(shù)據(jù)

那么MVP模式又是怎樣的呢?請看下圖

MVP模式示意圖

從上圖可以看出, 從MVC中又抽象出了P層, 即Presenter層

  • Controller其實將view和viewController傳遞給了P層, 這樣P層其實就擁有了控制器的權(quán)利, 完全可以行使控制器的職責(zé).

  • Controller又持有Presenter, 那么它只需要調(diào)用P層暴露出的接口, 就完全可以完成整個業(yè)務(wù)邏輯和頁面展示

關(guān)于C端和P端的循環(huán)引用的問題, 直接用weak關(guān)鍵字就可以解決了

利用代碼來說明一下問題:

  • 這是一個Presenter的Protocol, 所有的P層的類都要遵循這個Protocol

#import /**
  作為P : presenter 是管理 view viewController model這個三個中間人,負(fù)責(zé)UI刷新
  視圖的交互總是和VC 關(guān)聯(lián)著的
 */
@protocol TGPresenterProtocol @optional
// 處理View視圖相關(guān)操作 -- 協(xié)議的遵守者
- (void)setView:(NSObject *)view;
// 處理事件的相關(guān)響應(yīng)
- (void)setViewController:(UIViewController *)viewController;
// 展示
- (void)present;
// 加載model 
- (void)presentWithModel:(id)model viewController:(UIViewController *)viewController;
@end
  • 可以看出, P層是可以拿到view或者viewController的, 并且可以在實現(xiàn)set方法的時候做一些事情. 這個稍后再講

  • 另外, P層還可以展示數(shù)據(jù), 直接展示數(shù)據(jù), present方法, 利用模型展示數(shù)據(jù), 利用presentWithModel:方法

  • 比如, 在一個遵循了TGPresenterProtocol的Presenter類中

把需要管理的view傳遞給P,

- (instancetype)initWithTableView:(UITableView *)view{
    
    self = [super init];
    if (!self) {
        return nil;
    }
    _view = view;
    _view.delegate = self;
    _view.dataSource = self;
    _view.separatorStyle = UITableViewCellSeparatorStyleNone;
    // 自適應(yīng)高度
    _view.rowHeight = UITableViewAutomaticDimension;
    _view.estimatedRowHeight = 100;
    return self;
}
- (void)setView:(UITableView *)view{
    // 設(shè)置視圖
    _view = view;
    _view.delegate = self;
    _view.dataSource = self;
    _view.separatorStyle = UITableViewCellSeparatorStyleNone;
    // 自適應(yīng)高度
    _view.rowHeight = UITableViewAutomaticDimension;
    _view.estimatedRowHeight = 100;
}
  • 比如上面的代碼, 將tableView的數(shù)據(jù)源和代理都給了P, 那么P就相當(dāng)于行使了控制器的權(quán)力, 當(dāng)P層拿到數(shù)據(jù)時(沒錯, P層是持有Model的):

- (void)loadHPData{
    
    NSString *dataPath = [[NSBundle mainBundle] pathForResource:@"testCellData" ofType:@"json"];
    NSData *jsonData = [NSData dataWithContentsOfFile:dataPath];
    NSError *error;
    NSDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:&error];
    if (error) {
        NSLog(@"error = %@",error.localizedDescription);
    }
    NSLog(@"dataDic = %@",dataDic);
    // model 要處理好數(shù)據(jù)的顯示格式
    self.hpModel = [[CellSelfSizeModel alloc] initWithDic:dataDic];
    // 刷新
    [self present];
    
}
  • 走Present方法, 實際就是tableView的reloadData:

- (void)present{
    
    [self.view reloadData];
}
  • 然后重走tableView的數(shù)據(jù)源方法. 將數(shù)據(jù)分發(fā)給cell去展示:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    
    return self.hpModel.data.listArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    NSString *ID = @"";
    cellType type;
    
    CelllSelfSizeListModel *newsList;
    if (indexPath.row > self.hpModel.data.listArray.count - 1) {
        newsList = nil;
    }else{
        newsList = self.hpModel.data.listArray[indexPath.row];
    }
    if (newsList.orginImg.length>0) {
        // 有圖片
        type = NewsInListCellTypeHavePic;
        
    }else{
        // 無圖片
        type = NewsInListCellTypeOnlyWord;
    }
    
    ID = [NSString stringWithFormat:@"reusId%ld",(long)type];
    
    SelfSizeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[SelfSizeTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID cellType:type];
    }
    
    cell.cellModel = newsList;
    
    return cell;
}

這樣就實現(xiàn)了Controller, View, Model的解耦. 給大家看看控制器做的事情:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.title = @"MVP Demo";
//    布局
    [self initViews];
    [self setUpConstraints];
    
    self.hpPresenter = [TGHPPresenter new];
    // 視圖對象
    self.hpPresenter.view = self.tableView;
    // 控制器對象
    self.hpPresenter.viewController = self;
    // 外邊是要傳入?yún)⑦M去的 -- 數(shù)據(jù)模型
    [self.hpPresenter loadHPData];
    
}

只需要初始化P層, 然后調(diào)P層的接口就可以了. 至于P層內(nèi)部的邏輯, 我不需要知道

  • V層也只專注于視圖的創(chuàng)建

  • M層只專注于模型的構(gòu)建(字典->模型)

  • 這樣分層, 解耦的思想在程序設(shè)計中是極為重要的. 其實也可以看出MVP是對MVC模式的進一步抽象.

代碼Demo是我們老大寫的, 我只是分析了一波

 

來自:http://www.cocoachina.com/ios/20171106/21062.html

 

標(biāo)簽: 代碼 數(shù)據(jù)庫 網(wǎng)絡(luò)

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:Java在線問題排查利器之Btrace&Greys

下一篇:iOS藍(lán)牙開發(fā)CoreBluetooth框架總結(jié)