亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

寫給iOS小白的MVVM教程(一):從MVC到MVVM之一個典型的MVC應用場景

2019-11-14 18:08:19
字體:
來源:轉載
供稿:網友

前言

本著實踐為主的原則,此系列文章不做過多的概念性的闡述和討論;更多的代碼和篇幅用來展示MVC和MVVC下的基礎代碼結構與具體實現,來展示各自優劣.這篇文章,更多的在于發掘MVC與MVVC的共性,以期為那些對MVVC感興趣的iOS開發者,找到一種平滑的過渡與重構代碼的方式.如果對MVVC感興趣,可以直接將本文的大部分代碼引用到自己的項目中,畢竟代碼是寫出來的!開篇之前,你可以先到這里下載本文的示例工程: https://github.com/ios122/ios122

在這一篇章里,我會分別使用我所理解的MVC與MVVC兩種模式來完成同一個應用場景,以期幫助那些熟悉傳統MVC模式代碼的iOS攻城獅,能更好理解MVVC.限于篇幅,將MVC和MVVM拆分為兩個部分,今天要說的是一個典型的MVC的應用場景,為基于MVC的MVVM重構做個基礎.這篇文章著重進行了接口準備,必須的知識點的說明等內容.

預設場景:按分類請求一組博客,點擊獲取博客詳情

我們選取最常見的一組場景: 根據某種規則獲取一組數據,點擊某一條數據,可以跳轉到下一界面獲取數據詳情.這里我會根據分類請求此分類下的博客列表,點擊某一條信息,可跳轉到博客詳情頁.簡單說,其實我們真正需要實現的只有兩個頁面: 博客分類列表頁 與 博客詳情頁.

數據接口準備

我們至少需要兩個接口,一個可以根據分類來獲取博客列表,一個用來根據id獲取博客詳情.

使用預定義的接口

如果你沒有自己的服務器或者對服務器開發不熟悉,可以使用我準備的這兩個測試接口:

博客列表接口

http://www.ios122.com/find_php/index.php?viewController=YFPostListViewController&model[category]=ui&model[page]=2
  • ui分類名稱,目前預定義支持: ui, network, tool,autolayout 四個分類.
  • 2,獲取第幾頁的數據,從0開始計數,指請求此分類下第幾頁的數據.預定義每個分類下有100條數據,每20條數據一頁.
  • 返回示例:
[    {        "id": "ui_40",        "title": "title_ui_40",        "desc": "desc_ui_40"    },    {        "id": "ui_41",        "title": "title_ui_41",        "desc": "desc_ui_41"    },    {        "id": "ui_42",        "title": "title_ui_42",        "desc": "desc_ui_42"    },    {        "id": "ui_43",        "title": "title_ui_43",        "desc": "desc_ui_43"    },    {        "id": "ui_44",        "title": "title_ui_44",        "desc": "desc_ui_44"    },    {        "id": "ui_45",        "title": "title_ui_45",        "desc": "desc_ui_45"    },    {        "id": "ui_46",        "title": "title_ui_46",        "desc": "desc_ui_46"    },    {        "id": "ui_47",        "title": "title_ui_47",        "desc": "desc_ui_47"    },    {        "id": "ui_48",        "title": "title_ui_48",        "desc": "desc_ui_48"    },    {        "id": "ui_49",        "title": "title_ui_49",        "desc": "desc_ui_49"    },    {        "id": "ui_50",        "title": "title_ui_50",        "desc": "desc_ui_50"    },    {        "id": "ui_51",        "title": "title_ui_51",        "desc": "desc_ui_51"    },    {        "id": "ui_52",        "title": "title_ui_52",        "desc": "desc_ui_52"    },    {        "id": "ui_53",        "title": "title_ui_53",        "desc": "desc_ui_53"    },    {        "id": "ui_54",        "title": "title_ui_54",        "desc": "desc_ui_54"    },    {        "id": "ui_55",        "title": "title_ui_55",        "desc": "desc_ui_55"    },    {        "id": "ui_56",        "title": "title_ui_56",        "desc": "desc_ui_56"    },    {        "id": "ui_57",        "title": "title_ui_57",        "desc": "desc_ui_57"    },    {        "id": "ui_58",        "title": "title_ui_58",        "desc": "desc_ui_58"    },    {        "id": "ui_59",        "title": "title_ui_59",        "desc": "desc_ui_59"    }]

2.博客詳情接口

http://www.ios122.com/find_php/index.php?viewController=YFPostViewController&model[id]=ui_0
  • ui_0 表示博客唯一標識.其應為分類博客列表返回的一個有效id.
  • 返回示例:
{    "title": "title of ui_0",    "body": "<h2>Hello iOS122</h2> Scann To Join Us <br /> <image alt=/"QQ/" src=/"https://raw.githubusercontent.com/ios122/ios122/master/1443002712802.png/" />"}

自定義接口

如果你有自己的服務器接口,直接使用即可;但是下面的oc代碼,你可能也要對應變換下;如果你對服務器接口開發不是很了解,可以先閱讀下這篇文章: iOS程序猿如何快速掌握 PHP,化身”全棧攻城獅”?.

假定,你已經閱讀并領會了 << iOS程序猿如何快速掌握 PHP,化身”全棧攻城獅”? >>,這篇文章,新建問及那,并把下面的代碼復制到對應文件中,然后根據自己的需要更改即可:

博客列表接口源文件

<?php // YFPostListViewController.phpclass YFPostListViewController{  public $model = array(); //!< 傳入的數據.  PRivate $countOfPerPage = 20; //!< 每頁數據條數.  /* 獲取內容,用于輸出顯示. */  protected function getContent()  {    /* 預定義一組數據 */    $datasource = array();    $categorys = array('ui', 'network', 'tool', 'autolayout');    for ($i=0; $i < count($categorys); $i++) {      $categoryName = $categorys[$i];      $categoryData = array();      for ($j=0; $j < 100; $j++) {        $item = array(          'id' => "{$categoryName}_{$j}",          'title' => "title_{$categoryName}_{$j}",          'desc' => "desc_{$categoryName}_{$j}"        );        $categoryData[$j] = $item;      }      $datasource[$categoryName] = $categoryData;    }    $queryCategoryName = $this->model['category'];    $queryPage = $this->model['page'];    $targetCategoryData = $datasource[$queryCategoryName];    $content = array();    for ($i = $this->countOfPerPage * $queryPage ; $i < $this->countOfPerPage * ($queryPage + 1); $i ++ ) {      $content[] = $targetCategoryData[$i];    }    $content = json_encode($content);     return $content;  }  public function show()  {   $content = $this->getContent();   header("Content-type: application/json");   echo $content;  }}

博客詳情接口源文件

<?php // YFPostViewController.phpclass YFPostViewController{  public $model = array(); //!< 傳入的數據.  /* 獲取內容,用于輸出顯示. */  protected function getContent()  {    $id = $this->model['id'];    $content = array(      'title' => "title of {$id}",      'body' => '<h2>Hello iOS122</h2> Scann To Join Us <br /> <image alt="qq" src="https://raw.githubusercontent.com/ios122/ios122/master/1443002712802.png" />'    );    $content = json_encode($content);     return $content;  }  public function show()  {   $content = $this->getContent();   header("Content-type: application/json");   echo $content;  }}

MVC 版本實現: 類似的代碼,你不知道敲過了多少遍

技術要點

下面列出將要用到的技術點,如有你不熟悉的,可點擊對應鏈接訪問:

  • 使用 AFNetworking 來處理網絡請求;
  • 使用 MJExtension實現JSON到數據模型的自動轉換;
  • 使用 MJRefresh 實現下拉刷新與上拉加載更多的效果;
  • 使用 Masonry 進行AutoLayout布局;
  • 使用 MBProgressHUD 優化頁面加載時的進度提示;

思路分析

  • 博客分類列表頁面:
  1. 在前一頁面指定博客分類;
  2. 頁面加載時自動發起網絡請求獲取對應分類的數據;
  3. 獲取數據成功后,自動刷新視圖;獲取失敗,則給出錯誤提示;
  4. 點擊某一條數據,可跳轉到博客詳情頁.
  • 博客詳情頁面:
  1. 在前一頁面指定博客id;
  2. 頁面加載時自動發起網絡請求獲取id的博客詳情;
  3. 獲取成功后,自動刷新視圖;獲取失敗,則給出錯誤提示.

博客列表頁面

博客列表效果圖

1. 在前一頁面指定博客分類;

這一步,大家肯定都會:

YFMVCPostListViewController * mvcPostListVC = [[YFMVCPostListViewController alloc] init];    mvcPostListVC.categoryName = @"ui";    [self.navigationController pushViewController: mvcPostListVC animated: YES];

2. 頁面加載時自動發起網絡請求獲取對應分類的數據;

為了保證每次都能進入列表頁,都能自動刷新數據,建議在 viewWillAppear:方法刷新數據:

- (void)viewWillAppear:(BOOL)animated{    [super viewWillAppear: animated];        [self updateData];}

updateData方法進行數據的更新:

- (void)updateData{    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];        NSString * urlStr = [NSString stringWithFormat: @"http://www.ios122.com/find_php/index.php?viewController=YFPostListViewController&model[category]=%@&model[page]=0", self.categoryName];        [manager GET: urlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responSEObject) {        NSLog(@"JSON: %@", responseObject);    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {        NSLog(@"Error: %@", error);    }];}

此處使用的是預定義接口,數據請求成功后,控制臺輸入如下:

JSON: (        {        desc = "desc_ui_0";        id = "ui_0";        title = "title_ui_0";    },        {        desc = "desc_ui_1";        id = "ui_1";        title = "title_ui_1";    },        {        desc = "desc_ui_2";        id = "ui_2";        title = "title_ui_2";    },        {        desc = "desc_ui_3";        id = "ui_3";        title = "title_ui_3";    },        {        desc = "desc_ui_4";        id = "ui_4";        title = "title_ui_4";    },        {        desc = "desc_ui_5";        id = "ui_5";        title = "title_ui_5";    },        {        desc = "desc_ui_6";        id = "ui_6";        title = "title_ui_6";    },        {        desc = "desc_ui_7";        id = "ui_7";        title = "title_ui_7";    },        {        desc = "desc_ui_8";        id = "ui_8";        title = "title_ui_8";    },        {        desc = "desc_ui_9";        id = "ui_9";        title = "title_ui_9";    },        {        desc = "desc_ui_10";        id = "ui_10";        title = "title_ui_10";    },        {        desc = "desc_ui_11";        id = "ui_11";        title = "title_ui_11";    },        {        desc = "desc_ui_12";        id = "ui_12";        title = "title_ui_12";    },        {        desc = "desc_ui_13";        id = "ui_13";        title = "title_ui_13";    },        {        desc = "desc_ui_14";        id = "ui_14";        title = "title_ui_14";    },        {        desc = "desc_ui_15";        id = "ui_15";        title = "title_ui_15";    },        {        desc = "desc_ui_16";        id = "ui_16";        title = "title_ui_16";    },        {        desc = "desc_ui_17";        id = "ui_17";        title = "title_ui_17";    },        {        desc = "desc_ui_18";        id = "ui_18";        title = "title_ui_18";    },        {        desc = "desc_ui_19";        id = "ui_19";        title = "title_ui_19";    })

3. 獲取數據成功后,自動刷新視圖;獲取失敗,則給出錯誤提示;

這一部分,涉及的變動較多,我就直接貼代碼了.你會注意到View和數據已經交叉進行了,很亂的感覺.而這也是我們想要使用MVVM重構代碼的重要原因之一.

////  YFMVCPostListViewController.m//  iOS122////  Created by 顏風 on 15/10/14.//  Copyright (c) 2015年 iOS122. All rights reserved.//#import "YFMVCPostListViewController.h"#import "YFArticleModel.h"#import <AFNetworking.h>#import <MJRefresh.h>#import <MBProgressHUD.h>@interface YFMVCPostListViewController ()<UITableViewDelegate, UITableViewDataSource>@property (nonatomic, strong) UITableView * tableView;@property (nonatomic, strong) NSMutableArray * articles; //!< 文章數組,內部存儲AFArticleModel類型.@property (assign, nonatomic) NSInteger page; //!< 數據頁數.表示下次請求第幾頁的數據.@end@implementation YFMVCPostListViewController- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.}- (NSMutableArray *)articles{    if (nil == _articles) {        _articles = [NSMutableArray arrayWithCapacity: 42];    }        return _articles;}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}- (void)viewWillAppear:(BOOL)animated{    [super viewWillAppear: animated];    // 馬上進入刷新狀態    [self.tableView.header beginRefreshing];}- (UITableView *)tableView{    if (nil == _tableView) {        _tableView = [[UITableView alloc] init];                [self.view addSubview: _tableView];                [_tableView makeConstraints:^(MASConstraintMaker *make) {            make.edges.equalTo(UIEdgeInsetsMake(0, 0, 0, 0));        }];                _tableView.delegate = self;        _tableView.dataSource = self;                NSString * cellReuseIdentifier = NSStringFromClass([UITableViewCell class]);                [_tableView registerClass: NSClassFromString(cellReuseIdentifier) forCellReuseIdentifier:cellReuseIdentifier];                _tableView.header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{            self.page = 0;                        [self updateData];        }];                _tableView.footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{            [self updateData];        }];            }        return _tableView;}/** * 更新視圖. */- (void) updateView{    [self.tableView reloadData];}/** *  更新數據. * *  數據更新后,會自動更新視圖. */- (void)updateData{    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];        NSString * urlStr = [NSString stringWithFormat: @"http://www.ios122.com/find_php/index.php?viewController=YFPostListViewController&model[category]=%@&model[page]=%ld", self.categoryName, (long)self.page ++];        [manager GET: urlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {        [self.tableView.header endRefreshing];        [self.tableView.footer endRefreshing];                if (1 == self.page) { // 說明是在重新請求數據.            self.articles = nil;        }                NSArray * responseArticles = [YFArticleModel objectArrayWithKeyValuesArray: responseObject];                [self.articles addObjectsFromArray: responseArticles];                [self updateView];    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {        [self.tableView.header endRefreshing];        [self.tableView.footer endRefreshing];                MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];        hud.mode = MBProgressHUDModeText;        hud.labelText = @"您的網絡不給力!";        [hud hide: YES afterDelay: 2];    }];}# pragma mark - tabelView代理方法.- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    NSInteger number  = self.articles.count;        return number;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    NSString * cellReuseIdentifier = NSStringFromClass([UITableViewCell class]);        UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: cellReuseIdentifier forIndexPath:indexPath];        YFArticleModel * model = self.articles[indexPath.row];    NSString * content = [NSString stringWithFormat: @"標題:%@ 內容:%@", model.title, model.desc];        cell.textLabel.text = content;        return cell;}@end

4. 點擊某一條數據,可跳轉到博客詳情頁.

只需要再額外實現下 -tableView: didSelectRowAtIndexPath:方法即可:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{    // 跳轉到博客詳情.    YFArticleModel * articleModel = self.articles[indexPath.row];        YFMVCPostViewController * postVC = [[YFMVCPostViewController alloc] init];        postVC.articleID = articleModel.id;        [self.navigationController pushViewController: postVC animated: YES];}

博客詳情頁面

博客詳情效果圖

1. 在前一頁面指定博客id;

這里其實就是博客列表的控制器的那幾句:

// 跳轉到博客詳情.YFArticleModel * articleModel = self.articles[indexPath.row];    YFMVCPostViewController * postVC = [[YFMVCPostViewController alloc] init];    postVC.articleID = articleModel.id;    [self.navigationController pushViewController: postVC animated: YES];

2. 頁面加載時自動發起網絡請求獲取id的博客詳情;

此處為了方便,我們依然使用預定義的博客詳情接口:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];        NSString * urlStr = [NSString stringWithFormat: @"http://www.ios122.com/find_php/index.php?viewController=YFPostViewController&model[id]=%@", self.articleID];        [manager GET: urlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {        NSLog(@"%@", responseObject);                [self updateView];    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {                MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];        hud.mode = MBProgressHUDModeText;        hud.labelText = @"您的網絡不給力!";        [hud hide: YES afterDelay: 2];    }];

請求的輸入,Xcode控制臺打印輸出,類似于:

{    body = "<h2>Hello iOS122</h2> Scann To Join Us <br /> <image alt=/"qq/" src=/"https://raw.githubusercontent.com/ios122/ios122/master/1443002712802.png/" />";    title = "title of ui_0";}

3. 獲取成功后,自動刷新視圖;獲取失敗,則給出錯誤提示.

你會注意到,我們在上一步獲取的數據,body部分內部是HTML字符串,所以我們要使用webView來顯示博客詳情.這和最近炒得很火的的混合開發模式有些像,但是目前主流的博客應用,幾乎都是這么做的.完整代碼如下:

////  YFMVCPostViewController.m//  iOS122////  Created by 顏風 on 15/10/16.//  Copyright (c) 2015年 iOS122. All rights reserved.//#import "YFMVCPostViewController.h"#import "YFArticleModel.h"#import <AFNetworking.h>#import <MBProgressHUD.h>@interface YFMVCPostViewController ()<UIWebViewDelegate>@property (strong, nonatomic) UIWebView * webView;@property (strong, nonatomic) YFArticleModel * article;@end@implementation YFMVCPostViewController- (UIWebView *)webView{    if (nil == _webView) {        _webView = [[UIWebView alloc] init];                [self.view addSubview: _webView];                [_webView makeConstraints:^(MASConstraintMaker *make) {            make.edges.equalTo(UIEdgeInsetsMake(64, 0, 0, 0));        }];    }        return _webView;}- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}- (void)viewWillAppear:(BOOL)animated{    [super viewWillAppear: animated];        [self updateData];}/** * 更新視圖. */- (void) updateView{    [self.webView loaDHTMLString: self.article.body baseURL:nil];}/** *  更新數據. * *  數據更新后,會自動更新視圖. */- (void)updateData{    [MBProgressHUD showHUDAddedTo:self.view animated: YES];        AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];        NSString * urlStr = [NSString stringWithFormat: @"http://www.ios122.com/find_php/index.php?viewController=YFPostViewController&model[id]=%@", self.articleID];        [manager GET: urlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {        self.article = [YFArticleModel objectWithKeyValues: responseObject];                [self updateView];    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {                MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];        hud.mode = MBProgressHUDModeText;        hud.labelText = @"您的網絡不給力!";        [hud hide: YES afterDelay: 2];    }];}@end

小結

此篇主要展示了一個典型的列表-->詳情場景的MVC實現,相關技術代碼可以直接用于自己的項目中.盡管這是簡化的場景,但依然可以很明顯地看出來數據,網絡請求與視圖間的相互調用,使代碼整體的可復用性大大降低! 而這,也是我們下次要用 MVVC 重構這個示例的核心目的之一!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品国产电影一区| 欧美中文在线字幕| 国产精品电影久久久久电影网| 国产精品最新在线观看| 欧美性猛交xxxx偷拍洗澡| 国产精品久久久久久久7电影| 日韩电影中文字幕在线观看| 成人信息集中地欧美| 国产一区二区三区中文| 国产精品入口免费视频一| 精品久久久国产| 欧美国产视频一区二区| 国产精品成人一区二区| 午夜精品一区二区三区在线视| 日产日韩在线亚洲欧美| 亚洲xxxx妇黄裸体| 久久精品国产久精国产一老狼| 国产一区二区三区视频在线观看| 久久噜噜噜精品国产亚洲综合| 91av视频在线播放| 91大神在线播放精品| 这里只有精品视频| 国产精品美女免费| 成人国产精品久久久久久亚洲| 亚洲免费福利视频| www.国产精品一二区| 成人春色激情网| 黄色成人在线播放| 欧美亚洲视频在线看网址| 亚洲自拍欧美色图| 26uuu国产精品视频| 亚洲成人激情图| 精品视频在线播放色网色视频| 亚洲人成网站999久久久综合| 精品国产精品三级精品av网址| 久久成人国产精品| 一区二区三欧美| 久久99久久99精品免观看粉嫩| 国产精品吴梦梦| 欧美乱大交xxxxx| 超薄丝袜一区二区| 欧美日韩在线影院| 国产欧美日韩中文字幕| 大量国产精品视频| 国产精品一区二区三区久久久| 亚洲天堂男人天堂女人天堂| 欧美www视频在线观看| 国产69精品久久久| 国产精品美女主播在线观看纯欲| 国产精品盗摄久久久| 欧美大片大片在线播放| 国产日韩欧美在线播放| 国产视频在线一区二区| 国产精品视频在线播放| 在线观看91久久久久久| 欧洲亚洲免费视频| 中国china体内裑精亚洲片| 亚洲精品99久久久久中文字幕| 国产欧美日韩丝袜精品一区| 91系列在线观看| 亚洲精品国产精品国自产观看浪潮| 国产一区二区三区毛片| 尤物精品国产第一福利三区| 国产精品美女www爽爽爽视频| 91国语精品自产拍在线观看性色| 欧美日韩成人网| 国产亚洲欧美aaaa| 成人黄色免费片| 色先锋久久影院av| 国产成人综合精品在线| 日韩在线视频观看正片免费网站| 伊人男人综合视频网| 亚洲福利视频专区| 欧美野外wwwxxx| 亚洲欧美综合精品久久成人| 午夜精品久久久久久久男人的天堂| 午夜精品久久久久久久白皮肤| 性夜试看影院91社区| 亚州国产精品久久久| 欧美成人精品在线视频| 欧美成aaa人片免费看| 日本不卡高字幕在线2019| 国产成人自拍视频在线观看| 91精品国产电影| 久久精品国产亚洲一区二区| 亚洲欧美一区二区三区四区| 日本一区二区三区四区视频| 久久久精品网站| 国产精品久久久久久久一区探花| 亚洲电影免费观看| 久久久久久91| 欧美日韩一区二区在线播放| 成人在线小视频| 日韩在线观看免费高清| 国产精品福利网| 欧美日韩国产成人在线| 欧美精品电影免费在线观看| 久久精品国产成人精品| 4438全国成人免费| 日韩国产高清视频在线| 亚洲一区二区三区在线免费观看| 日韩在线视频观看| 欧美性极品xxxx做受| 欧美日韩另类字幕中文| 国产欧美日韩中文字幕| 在线电影中文日韩| 亚洲精品之草原avav久久| 91亚洲精品久久久久久久久久久久| 91人成网站www| 亚洲欧美日韩精品| 26uuu另类亚洲欧美日本老年| 韩国19禁主播vip福利视频| 欧洲精品在线视频| 欧美大片免费观看| 日韩av电影中文字幕| 欧美性猛交xxxx黑人| 国产999视频| 69久久夜色精品国产69乱青草| 亚洲乱码国产乱码精品精| 欧美一级黑人aaaaaaa做受| 亚洲国产福利在线| 亚洲综合国产精品| 国产精品入口免费视| 97在线视频国产| 国产精品久久久久av免费| 国产一区二区三区视频在线观看| 8090理伦午夜在线电影| 亚洲精品免费在线视频| 亚洲精品自拍第一页| 亚洲国产精品久久久久秋霞不卡| 97国产精品免费视频| 人体精品一二三区| 亚洲欧美日韩精品久久奇米色影视| 国产成人精品电影| 成人写真福利网| 欧美日韩一二三四五区| 国内精品视频在线| 在线电影欧美日韩一区二区私密| 97精品在线视频| 成人国产精品av| 最近2019年中文视频免费在线观看| 日韩在线免费视频观看| 日本a级片电影一区二区| 日韩中文在线中文网在线观看| xxx一区二区| 成人在线激情视频| 最近2019年日本中文免费字幕| 亚洲第一二三四五区| 日本久久久a级免费| 亚洲人成在线观看| 91性高湖久久久久久久久_久久99| 日韩精品丝袜在线| 亚洲欧美国产日韩天堂区| 国产精品久久久久久久久久东京| 亚洲欧美视频在线| 91av在线播放视频| 色综合伊人色综合网站| 亚洲国产精品网站| 国产精品永久在线| 欧美激情精品久久久久久蜜臀| 国产一区二区三区在线观看视频| 韩国国内大量揄拍精品视频| 成人国产精品免费视频| 欧美日韩国产二区|