精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

iOS組件化不只是架構師的事

移動開發
為什么要組件化,在看過很多優秀的文章后,你一定會問這個問題,組件化能給我們帶來多大的好處?作為一個小公司而言,涉及組件化的機會很少,沒有大廠的工作經驗,也很難將組件化理解的很透徹。

iOS組件化曾今在業界是多么的火熱的話題,現在在少有人再次提及這個的話題。網上也很多關于組件化的文章和思想,最經典的要是casa大神和蘑菇街關于組件化的論戰。想想曾經看到這些文章的時候,覺得組件化是多么優秀的思想,覺得他們說的都有道理,而casa大神應該在很多思想上給了我等碼農很多靈感。而兩位大神架構師級別的論劍是否讓你真正理解到組件化的重要性。是否讓你在內心深處產生共鳴,最 近看到一個項目讓我對組件化多了些思考。

[[249145]]

一、為什么要組件化,組件化到底有什么好處?

為什么要組件化,在看過很多優秀的文章后,你一定會問這個問題,組件化能給我們帶來多大的好處?作為一個小公司而言,涉及組件化的機會很少,沒有大廠的工作經驗,也很難將組件化理解的很透徹。可能以為我們的業務模塊還不夠多,或者說,我們沒有理解到他的好處,其實組件化***的好處就是,每個組件,每個模塊都可能單獨成一個app,具有自己的生命周期。這樣就可以分割成不同的業務組模塊去處理,之前聽說京東,有團隊專門負責消息模塊,有團隊專門負責廣告模塊,有團隊專門負責發現模塊,這是你就會發現如果沒有很好的組件化思想,這樣的多團隊合作就非常的困難,已經很難維護好這個項目的開發迭代。說了這么多,到底組件化是什么樣子的呢?那我跟著我的腳步,學習分析,探討下。

二、組件化的核心思想

組件化的話的核心思想,也是我們進行組件化的基礎框架,就是通過怎么樣的方式實現組件化,或者如何從架構層,業務層多個層次實現架構呢。要想實現組件化,其實就是建立一個中間轉換的工具。你也可以理解為路由,通過路由的思想實現跨業務的數據溝通,從而一定程度上的降低各層數據的耦合。減少各個業務層等層級的import發生的耦合。

三、目前實現的組件化的方式

目前實現一般有下面三種思想:

  1. Procotol方案
  2. URL路由方案
  3. target-action方案

Procotol協議注冊方案

關于procotol協議注冊方案看人用的比較少,也很少看到有人分享,我也是在這個項目中看到,就研究了一下。通過JJProtocolManager 作為中間轉化。 

  1. + (void)registerModuleProvider:(id)provider forProtocol:(Protocol*)protocol;  
  2. + (id)moduleProviderForProtocol:(Protocol *)protocol; 

所有組件對外提供的procotol和組件提供的服務由中間件統一管理,每個組件提供的procotol和服務是一一對應的。

例如:

在JJLoginProvider中:load方法會應用啟動的時候調用,就會在JJProtocolManager進行注冊。JJLoginProvider遵守了JJLoginProvider協議,這樣就可以對外根據業務需求提供一些方法。 

  1. + (void)load 
  2.     [JJProtocolManager registerModuleProvider:[self new] forProtocol:@protocol(JJLoginProtocol)]; 
  3. - (UIViewController *)viewControllerWithInfo:(id)userInfo needNew:(BOOL)needNew callback:(JJModuleCallbackBlock)callback{ 
  4.     CLoginViewController *vc = [[CLoginViewController alloc] init]; 
  5.     vc.jj_moduleCallbackBlock = callback; 
  6.     vc.jj_moduleUserInfo = userInfo; 
  7.     return vc; 

這樣就可以在需要登錄業務模塊的地方,通過JJProtocolManager取出JJLoginProtocol對應的服務提供者JJLoginProvider,直接獲取。如下: 

  1. id<jjwebviewvcmoduleprotocol> provider = [JJProtocolManager moduleProviderForProtocol:@protocol(JJWebviewVCModuleProtocol)]; 
  2.    UIViewController *vc =[provider viewControllerWithInfo:obj needNew:YES callback:^(id info) { 
  3.        if (callback) { 
  4.            callback(info); 
  5.        } 
  6.    }]; 
  7.    vc.hidesBottomBarWhenPushed = YES; 
  8.    [self.currentNav pushViewController:vc animated:YES];</jjwebviewvcmoduleprotocol> 

URL路由方案

URL路由方案最經典的就是蘑菇街的路由組件化,通過url的方式將調用方法,調用參數,已經回調方法封裝到url中,然后在通過對url的解析獲取到方法名,參數,***通過消息轉發機制調用方法。

下面是蘑菇街的路由方式:(這里要是想詳細了解,可以到蘑菇街的路由組件化 中具體學習) 

  1. [MGJRouter registerURLPattern:@"mgj://detail?id=:id" toHandler:^(NSDictionary *routerParameters) { 
  2.     NSNumber *id = routerParameters[@"id"]; 
  3.     // create view controller with id 
  4.     // push view controller 
  5. }]; 

首頁只需調用 [MGJRouter openURL:@"mgj://detail?id=404"] 就可以打開相應的詳情頁。

這里可以看到,我們通過url短鏈的方式,通過將參數拼接到url query部分,這樣就可以,通過這樣解析url中的scheme,host,path,query獲取到調轉什么要的控制器,需要傳什么什么樣的參數,從而push或者present新頁面。

解析scheme,host,path核心代碼: 

  1. NSString *scheme = [nsUrl scheme];//解析scheme 
  2.    NSString *module = [nsUrl host]; 
  3.    NSString *action = [[nsUrl path] stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; 
  4.    if (action && [action length] && [action hasPrefix:@"_"]) { 
  5.        action = [action stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:@""]; 
  6.    } 
  7.   
  8.    NSString *query = nil; 
  9.    NSArray* pathInfo = [nsUrl.absoluteString componentsSeparatedByString:@"?"]; 
  10.    if (pathInfo.count > 1) { 
  11.        query = [pathInfo objectAtIndex:1]; 
  12.    } 

解析query的核心代碼: 

  1. NSMutableDictionary *parameters = nil; 
  2. NSString *parametersString = query; 
  3. NSArray *paramStringArr = [parametersString componentsSeparatedByString:@"&"]; 
  4. if (paramStringArr && [paramStringArr count]>0) { 
  5.     parameters = [NSMutableDictionary dictionary]; 
  6.     for (NSString* paramString in paramStringArr) { 
  7.         NSArray *paramArr = [paramString componentsSeparatedByString:@"="]; 
  8.         if (paramArr.count > 1) { 
  9.             NSString *key = [paramArr objectAtIndex:0]; 
  10.             NSString *value = [paramArr objectAtIndex:1]; 
  11.             parameters[key] = [JJRouter unescapeURIComponent:value]; 
  12.         } 
  13.     } 
  14. return parameters; 

通過這樣的方式,我們就可以實現組件化,但是有時候我們會遇到一個圖片編輯模塊,不能傳遞UIImage到對應的模塊上去的話,這里我們需要傳個新的參數進去,為了解決這個問題,這樣其實,可以把參數直接丟給后面的arg處理

  1. + (nullable id)openURL:(nonnull NSString *)urlString arg:(nullable id)arg error:( NSError*__nullable *__nullable)error completion:(nullable JJRouterCompletion)completion 

舉個例子: 

  1.     Action *action = [Action new]; 
  2.            action.type = JJ_WebView; 
  3.            Params *params = [[Params alloc] init]; 
  4.            //            params.pageID = JJ_LOGIN; 
  5.            action.params = params; 
  6.            NSDictionary *parms = @{Jump_Key_Action:action, Jump_Key_Param : @{WebUrlString:@"http://www.baidu.com",Name:@"小二"}, Jump_Key_Callback:[JJFunc callback:^(id  _Nullable object) { 
  7.                NSLog(@"%@",object); 
  8.            }]}; 
  9. //            ActionJump(parms); 
  10.              
  11.            [JJRouter openURL:@"router://JJActionService/showWebVC" arg: parms error:nil completion:parms[Jump_Key_Callback]]; 
  12.        } 

我看的項目,這個就是通過url解析和protocol協議注冊實現組件化,只是沒有像蘑菇街那樣注冊支持哪些 URL類型。

target-action方案

target-action方案是在學習casa大神,CTMediator 的基礎上進行的

casa大神認為,

  1. 根本無法表達非常規對象,如果用url組件化的話,遇到像UIImage這樣的參數,就需要添加一個參數,才能解決
  2. URL注冊對于實施組件化方案是完全不必要的,且通過URL注冊的方式形成的組件化方案,拓展性和可維護性都會被打折
  3. 蘑菇街沒有拆分遠程調用和本地間調用
  4. 蘑菇街必須要在app啟動時注冊URL響應者 
  1. //理論上頁面之間的跳轉只需 open 一個 URL 即可。所以對于一個組件來說,只要定義「支持哪些 URL」即可,比如詳情頁,大概可以這么做的  
  2. [MGJRouter registerURLPattern:@"mgj://detail?id=:id" toHandler:^(NSDictionary *routerParameters) { 
  3.    NSNumber *id = routerParameters[@"id"]; 
  4.    // create view controller with id 
  5.    // push view controller 
  6. }]; 

而casa的組件化主要是基于Mediator模式和Target-Action模式,中間采用了runtime來完成調用。這套組件化方案將遠程應用調用和本地應用調用做了拆分,而且是由本地應用調用為遠程應用調用提供服務,與蘑菇街方案正好相反。

調用方式:

先說本地應用調用,本地組件A在某處調用[[CTMediator sharedInstance] performTarget:targetName action:actionName params:@{...}]向CTMediator發起跨組件調用,CTMediator根據獲得的target和action信息,通過objective-C的runtime轉化生成target實例以及對應的action選擇子,然后最終調用到目標業務提供的邏輯,完成需求。

在遠程應用調用中,遠程應用通過openURL的方式,由iOS系統根據info.plist里的scheme配置找到可以響應URL的應用(在當前我們討論的上下文中,這就是你自己的應用),應用通過AppDelegate接收到URL之后,調用CTMediator的openUrl:方法將接收到的URL信息傳入。當然,CTMediator也可以用openUrl:options:的方式順便把隨之而來的option也接收,這取決于你本地業務執行邏輯時的充要條件是否包含option數據。傳入URL之后,CTMediator通過解析URL,將請求路由到對應的target和action,隨后的過程就變成了上面說過的本地應用調用的過程了,最終完成響應。

針對請求的路由操作很少會采用本地文件記錄路由表的方式,服務端經常處理這種業務,在服務端領域基本上都是通過正則表達式來做路由解析。App中做路由解析可以做得簡單點,制定URL規范就也能完成,最簡單的方式就是scheme://target/action這種,簡單做個字符串處理就能把target和action信息從URL中提取出來了。

舉個例子: 

  1. /** 
  2. 這里是登錄模塊的target 
  3. **/ 
  4. #import "CTMediator+ModuleLogin.h" 
  5. NSString * const kCTMediatorTargetA = @"A"
  6. NSString * const kCTMediatorActionLoginViewController = @"showLoginController"
  7. @implementation CTMediator (ModuleLogin) 
  8. - (UIViewController *)push_viewControllerForLogin 
  9.    UIViewController *vc = [self performTarget:kCTMediatorTargetA action:kCTMediatorActionLoginViewController params:nil shouldCacheTarget:NO]; 
  10.      
  11.    if ([vc isKindOfClass:[UIViewController class]]) { 
  12.        // view controller 交付出去之后,可以由外界選擇是push還是present 
  13.        return vc; 
  14.    } else { 
  15.        // 這里處理異常場景,具體如何處理取決于產品 
  16.        return [[UIViewController alloc] init]; 
  17.    } 

 

  1. /** 
  2. 登錄模塊的action 
  3. **/ 
  4. - (UIViewController *)Action_showLoginController:(NSDictionary *)param 
  5.    JJLoginViewController *vc =[[JJLoginViewController alloc] init]; 
  6.      
  7.    return vc; 

看上去,target-action路由方案更加的清晰,不過這個還是各取所需吧

接下來,target-action的核心代碼就是: 

  1. /** 
  2. if ([target respondsToSelector:action]) 
  3. 判斷target能否響應action方法,只要能夠就執行這段核心代碼, 
  4. 核心代碼的主要功能: 
  5. **/ 
  6. - (id)safePerformAction:(SEL)action target:(NSObject *)target params:(NSDictionary *)params 
  7.    //// 創建一個函數簽名,這個簽名可以是任意的,但需要注意,簽名函數的參數數量要和調用的一致。 
  8.    NSMethodSignature* methodSig = [target methodSignatureForSelector:action]; 
  9.    if(methodSig == nil) { 
  10.        return nil; 
  11.    } 
  12. //    獲取返回類型 
  13.    const char* retType = [methodSig methodReturnType]; 
  14. //判斷返回值類型 
  15.    if (strcmp(retType, @encode(void)) == 0) { 
  16. // 通過簽名初始化 
  17.        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig]; 
  18. //如果此消息有參數需要傳入,那么就需要按照如下方法進行參數設置,需要注意的是,atIndex的下標必須從2開始。原因為:0 1 兩個參數已經被target 和selector占用 
  19.        [invocation setArgument:¶ms atIndex:2]; 
  20. // 設置selector 
  21.        [invocation setSelector:action]; 
  22. // 設置target 
  23.        [invocation setTarget:target]; 
  24. //消息調用 
  25.        [invocation invoke]; 
  26.        return nil; 
  27.    } 
  28.    if (strcmp(retType, @encode(NSInteger)) == 0) { 
  29.        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig]; 
  30.        [invocation setArgument:¶ms atIndex:2]; 
  31.        [invocation setSelector:action]; 
  32.        [invocation setTarget:target]; 
  33.        [invocation invoke]; 
  34.        NSInteger result = 0; 
  35.        [invocation getReturnValue:&result]; 
  36.        return @(result); 
  37.    } 
  38.    if (strcmp(retType, @encode(BOOL)) == 0) { 
  39.        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig]; 
  40.        [invocation setArgument:¶ms atIndex:2]; 
  41.        [invocation setSelector:action]; 
  42.        [invocation setTarget:target]; 
  43.        [invocation invoke]; 
  44.        BOOL result = 0; 
  45.        [invocation getReturnValue:&result]; 
  46.        return @(result); 
  47.    } 
  48.    if (strcmp(retType, @encode(CGFloat)) == 0) { 
  49.        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig]; 
  50.        [invocation setArgument:¶ms atIndex:2]; 
  51.        [invocation setSelector:action]; 
  52.        [invocation setTarget:target]; 
  53.        [invocation invoke]; 
  54.        CGFloat result = 0; 
  55.        [invocation getReturnValue:&result]; 
  56.        return @(result); 
  57.    } 
  58.    if (strcmp(retType, @encode(NSUInteger)) == 0) { 
  59.        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig]; 
  60.        [invocation setArgument:¶ms atIndex:2]; 
  61.        [invocation setSelector:action]; 
  62.        [invocation setTarget:target]; 
  63.        [invocation invoke]; 
  64.        NSUInteger result = 0; 
  65.        [invocation getReturnValue:&result]; 
  66.        return @(result); 
  67.    } 
  68. #pragma clang diagnostic push 
  69. #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 
  70.    return [target performSelector:action withObject:params]; 
  71. #pragma clang diagnostic pop 

總結:

CTMediator根據獲得的target和action信息,通過objective-C的runtime轉化生成target實例以及對應的action選擇子,然后最終調用到目標業務提供的邏輯,完成需求。

下面是三種方式的代碼實現Git的地址:

https://github.com/lumig/JJRouterDemo

彩蛋: 

  1. // url 編碼格式 
  2. foo://example.com:8042/over/there?name=ferret#nose 
  3. \_/ \______________/ \________/\_________/ \__/ 
  4. |         |              |         |        | 
  5. scheme authority         path      query   fragment 
  6. scheme://host.domain:port/path/filename 
  7. scheme - 定義因特網服務的類型。最常見的類型是 http 
  8. host - 定義域主機(http 的默認主機是 www) 
  9. domain - 定義因特網域名,比如 w3school.com.cn 
  10. :port - 定義主機上的端口號(http 的默認端口號是 80) 
  11. path - 定義服務器上的路徑(如果省略,則文檔必須位于網站的根目錄中)。 
  12. filename - 定義文檔/資源的名稱 

 

責任編輯:未麗燕 來源: 簡書
相關推薦

2015-11-24 10:05:07

私有云虛擬化負載遷移

2017-03-25 21:13:38

JavaScript排序

2010-08-05 09:29:08

jQuery

2013-04-25 13:58:15

編程

2011-04-28 20:21:44

和信創天終端管理虛擬終端管理系統

2024-11-26 11:02:17

2018-03-13 15:00:22

智慧交通高鐵無人駕駛

2021-11-05 11:17:45

互聯網996大廠

2012-09-18 10:20:17

2022-11-02 11:48:03

Vanilla OSGNOMEUbuntu

2015-03-31 09:28:28

Hadoop大數據技術大數據未來道路

2018-06-27 17:24:24

華為

2011-06-29 16:29:19

2021-07-26 22:33:41

切片結構體代碼

2025-04-17 02:00:00

數據分析SQL大數據

2025-04-08 03:00:00

2016-10-13 18:06:09

云計算多云模型

2015-12-15 17:19:55

戴爾云計算

2021-01-06 10:51:39

云計算云服務IT

2015-02-04 09:45:40

點贊
收藏

51CTO技術棧公眾號

成人免费视频网址| 欧美视频一二三区| 蜜桃久久影院| 在线观看亚洲国产| 欧美婷婷在线| 亚洲欧美综合精品久久成人| 中文国产在线观看| 成人黄色动漫| 中文字幕亚洲区| 国产视频99| 91中文字幕在线视频| 亚洲美女少妇无套啪啪呻吟| 中文字幕国产日韩| 久草视频福利在线| 亚洲精品大全| 一本一道波多野结衣一区二区| 在线观看福利一区| 牛牛澡牛牛爽一区二区| 国产精品一级二级三级| 国产成人免费91av在线| 国产一级免费观看| 91综合久久一区二区| 日韩激情视频在线播放| 久久精品一卡二卡| 成人黄色免费观看| 欧美日韩美女在线| 精品成在人线av无码免费看| 麻豆传媒视频在线| 亚洲国产精品精华液ab| 国产精品一区二区不卡视频| 国产美女三级无套内谢| 日本特黄久久久高潮| 91成人国产在线观看| 欧美日韩人妻精品一区二区三区| 青青草91久久久久久久久| 日韩激情在线视频| 欧美肉大捧一进一出免费视频| 国产一区精品二区| 69久久夜色精品国产69蝌蚪网| 97公开免费视频| 樱桃视频成人在线观看| 亚洲va国产天堂va久久en| 男女裸体影院高潮| 超碰在线无需免费| 亚洲手机成人高清视频| 一区二区三区四区五区视频| sese一区| 国产欧美一区视频| 日韩av综合中文字幕| 国产成人精品福利一区二区三区| 在线观看亚洲国产| 青青草视频一区| 国产mv久久久| 亚洲 欧美 中文字幕| 在线综合视频| 国产最新精品视频| www.国产成人| 国产亚洲一级| 日本精品视频网站| 波多野结衣视频网址| 老司机一区二区三区| 2019最新中文字幕| 亚洲第一网站在线观看| 日韩av一级电影| 国产精品永久免费视频| 7777久久亚洲中文字幕| 精品亚洲成a人在线观看| 成人激情综合网| 99在线观看免费| 成人综合激情网| 国产一区二区中文字幕免费看| 天堂在线资源8| 久久久久久久综合狠狠综合| 日韩国产美国| 国产淫片在线观看| 亚洲国产乱码最新视频 | 国产精品久久久久久超碰| 国产精品xxxxxx| 久久se精品一区二区| 亚洲自拍偷拍色片视频| 黄色小视频免费在线观看| 99久久99久久综合| 水蜜桃一区二区三区| 秋霞成人影院| 午夜精品福利一区二区三区av | 超碰中文字幕在线| 蜜臀久久久久久久| 粉嫩高清一区二区三区精品视频 | 中文字幕精品三区| 色爽爽爽爽爽爽爽爽| 国产传媒在线| 欧美日韩一区在线| 国产精品久久久久久亚洲色| 国产探花一区在线观看| 久久偷看各类女兵18女厕嘘嘘| 国产精品成人久久| 日韩在线播放视频| 欧美激情精品久久久久久小说| 欲香欲色天天天综合和网| 在线视频国内一区二区| 国产探花在线观看视频| 日韩成人动漫在线观看| 色妞在线综合亚洲欧美| 久草精品视频在线观看| av免费在线不卡| 蜜桃视频第一区免费观看| 亚洲xxx视频| 麻豆影视在线| 一区二区三区.www| 一区二区三区 日韩| 99热这里只有精品首页| 在线播放日韩精品| 日本视频免费在线| 黄色资源网久久资源365| 激情久久av| 国产在线激情| 在线亚洲精品福利网址导航| 精品1卡二卡三卡四卡老狼| 久久精品av| 日韩免费精品视频| 欧美一级在线免费观看| 中文字幕欧美一区| 免费观看成人网| 狼人天天伊人久久| 欧美激情第三页| 国产乱淫a∨片免费视频| 久久精品一二三| www.浪潮av.com| 国产精品17p| 九九热精品视频在线播放| 国产成人a v| 2020国产精品| 欧美精品99久久| 国偷自产视频一区二区久| 欧美猛交ⅹxxx乱大交视频| 国产精品国产精品国产| 久久免费美女视频| 国产成人a亚洲精v品无码| 国产伦理久久久久久妇女| 九九精品在线视频| 亚洲高清在线观看视频| 樱桃视频在线观看一区| 伦伦影院午夜理论片| 亚洲成人精品| 亚洲精品免费在线视频| 精品麻豆一区二区三区| 4438x成人网最大色成网站| 99自拍偷拍视频| 毛片一区二区三区| 一区二区三区四区国产| 成人av在线播放| 欧美成人激情视频免费观看| 国产美女无遮挡永久免费| 亚洲免费在线视频一区 二区| 激情黄色小视频| 久久久久久久久久久妇女| 国产日本欧美视频| www免费在线观看| 日韩视频一区二区| 日本三级网站在线观看| 91一区在线观看| 任你操这里只有精品| 精品国产乱码久久久久久果冻传媒 | 国产又粗又猛又爽又黄av| 日本不卡在线视频| 亚洲一二三区精品| 国产一区二区三区亚洲综合| 欧美激情一区二区三级高清视频| 六月丁香色婷婷| 精品久久久视频| 懂色av蜜桃av| 国产一区二区三区在线观看免费视频 | 福利在线播放| 777欧美精品| 精品一区免费观看| 久久久美女毛片| www.se五月| 亚洲区第一页| 水蜜桃一区二区三区| 一区二区三区四区视频免费观看| 97视频免费看| 日韩一二三四| 欧美日韩极品在线观看一区| 加勒比av在线播放| 久久久不卡影院| 俄罗斯女人裸体性做爰| 亚洲伊人网站| 中文字幕一区二区三区在线乱码| 一区二区在线免费播放| 日韩av免费网站| 菠萝菠萝蜜在线视频免费观看| 精品国产百合女同互慰| 天堂网免费视频| 亚洲欧美日韩在线播放| www.免费av| 国内精品视频一区二区三区八戒| 丰满爆乳一区二区三区| 欧美gayvideo| 美女视频久久| 欧美二区观看| 国产精品久久久久久久9999| 国模雨婷捆绑高清在线| 色老头一区二区三区在线观看| 亚洲欧美黄色片| 欧美日韩你懂得| 五月婷婷亚洲综合| 亚洲激情男女视频| 精品熟妇无码av免费久久| 成人美女视频在线看| 日本 片 成人 在线| 国产精品久久久亚洲一区| 日本三日本三级少妇三级66| 欧美亚洲激情| 欧美日韩另类综合| 国产精品18hdxxxⅹ在线| 国产日韩换脸av一区在线观看| 捆绑调教日本一区二区三区| 欧美大片免费观看在线观看网站推荐| 第九色区av在线| 亚洲精品综合精品自拍| 欧美视频一二区| 日韩一区二区在线看| 中文字幕免费高清在线观看| 日韩欧美在线网址| 1级黄色大片儿| 亚洲一区二区在线播放相泽| tube国产麻豆| 中文字幕日韩av资源站| jizz18女人高潮| 国产视频一区在线观看| 黄色a一级视频| 91丨porny丨在线| 艳妇乳肉豪妇荡乳xxx| 国产成人在线免费观看| 青娱乐国产精品视频| 久久er99精品| 日本美女视频一区| 久久国产成人午夜av影院| 九九九在线观看视频| 日韩在线观看一区二区| 精品久久久久久无码国产| 麻豆精品网站| 久久精品一区二| 久久久天天操| 亚洲五月天综合| 日产国产欧美视频一区精品| 熟女少妇精品一区二区| 老司机免费视频久久| 国产视频在线视频| 久久精品免费观看| 国产欧美激情视频| 国产精品亚洲а∨天堂免在线| 激情图片中文字幕| 国产精品一区免费视频| 中国男女全黄大片| proumb性欧美在线观看| 亚洲av无码国产精品久久| 久久久亚洲欧洲日产国码αv| 性猛交ⅹxxx富婆video | 亚洲 国产 日韩 综合一区| 精品国产aⅴ| 裸体裸乳免费看| 亚洲视频观看| 男人亚洲天堂网| 日本欧美一区二区| 香蕉视频色在线观看| 成人午夜视频福利| 90岁老太婆乱淫| 国产精品久久毛片av大全日韩| 一级性生活免费视频| 一区二区三区精品视频在线| 日韩三级一区二区三区| 日本韩国欧美国产| 国产免费福利视频| 亚洲精品ady| 92国产在线视频| 久久99国产精品久久久久久久久| 超级白嫩亚洲国产第一| 国产国产精品人在线视| 97精品资源在线观看| 国产精品亚洲综合| 日韩精品免费一区二区三区| 国产在线拍揄自揄拍无码| 99国产精品久久久久久久成人热| 久久精品香蕉视频| 国产成人精品一区二| 少妇真人直播免费视频| 亚洲精品中文在线观看| 黑人精品无码一区二区三区AV| 欧美日韩精品综合在线| 秋霞视频一区二区| 中文字幕一区二区三区电影| 高清电影在线观看免费| 国产精品久久久久久影视| av毛片精品| 亚洲一区尤物| 免费亚洲网站| 国产精品一级无码| 国产精品视频免费看| 日韩高清免费av| 欧美一区二区在线视频| 国产视频二区在线观看| 欧美刺激性大交免费视频| 日本成人伦理电影| 精品国产_亚洲人成在线| 亚洲成人国产| 在线免费av播放| 久久精品夜色噜噜亚洲a∨| 欧美黄色免费观看| 欧美日韩午夜影院| 日韩电影免费| 久久人人97超碰精品888| 只有精品亚洲| 水蜜桃亚洲一二三四在线| 国产毛片久久| 精品1卡二卡三卡四卡老狼| 亚洲欧洲成人精品av97| 中文av免费观看| 亚洲三级 欧美三级| mm视频在线视频| 91精品国产91久久久久青草| 久久视频在线| 黄色片视频在线| 国产午夜精品一区二区三区四区 | 欧美天堂亚洲电影院在线播放| 人妻丰满熟妇av无码区hd| 欧美成人自拍视频| 国产精品久久久久久久久久辛辛 | 国产成人精品三级| 国产精品美女高潮无套| 日韩欧中文字幕| 全色精品综合影院| 欧美一级淫片videoshd| 国产精品xxxav免费视频| 欧美乱做爰xxxⅹ久久久| 国产麻豆精品视频| 国产av 一区二区三区| 制服丝袜成人动漫| 国产在线观看a| av一区二区在线看| 欧美三级免费| 精品少妇人妻av一区二区三区| 一区二区日韩av| 亚洲av无码片一区二区三区 | 99久精品国产| 日韩 欧美 中文| 亚洲欧美成人网| 免费污视频在线一区| 日韩在线第一区| 久久99久久99精品免视看婷婷| 国产成人免费在线观看视频| 欧美日韩aaa| 婷婷色在线播放| 国产精品一区而去| 免费日韩av| 日本猛少妇色xxxxx免费网站| 欧美日韩视频在线第一区 | 久久精品无码一区二区三区毛片| 亚洲色图20p| 亚洲精品喷潮一区二区三区| 97视频在线观看免费高清完整版在线观看 | 成人性生交大片免费观看网站| 免费成人在线观看av| 日韩和欧美的一区| 日本美女黄色一级片| 欧美一区二区免费视频| 999福利在线视频| 日韩在线三级| 国模娜娜一区二区三区| 久久国产在线视频| 亚洲精品一区在线观看香蕉 | 国产不卡一区二区在线观看| 99在线观看免费视频精品观看| 级毛片内射视频| 91精品一区二区三区久久久久久| 亚洲小说区图片| 久久综合一区二区三区| 蜜臂av日日欢夜夜爽一区| 国产大片免费看| 国产视频在线观看一区二区| 免费成人高清在线视频| 久久99久久久久久| 国产欧美日韩视频一区二区| 国产熟女一区二区三区五月婷 | 国产精品伊人| www精品久久| 国产精品乱人伦| 日韩有码第一页| 国产日本欧美一区| 美女免费视频一区二区| 国产精品我不卡| 亚洲中字黄色| 自拍偷拍第9页| 精品国产区一区| 韩日精品一区| www.av91| 人人精品久久| 国产精品999视频| 国产精品久久久久久亚洲伦| 欧美一区二区公司|