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

iOS無侵入的埋點方案如何實現?

開發 開發工具
在開發過程中,埋點可以解決兩大類問題:一是了解用戶使用 App 的行為,二是降低分析線上問題的難度。

 [[324417]]

在開發過程中,埋點可以解決兩大類問題:一是了解用戶使用 App 的行為,二是降低分析線上問題的難度。目前,iOS 開發中常見的埋點方式,主要包括:

  • 代碼埋點
  • 可視化埋點
  • 無埋點

代碼埋點

代碼埋點主要就是通過手寫代碼的方式來埋點,能很精確的在需要埋點的代碼處加上埋點的代碼,可以很方便地記錄當前環境的變量值,方便調試,并跟蹤埋點內容,但存在開發工作量大,并且埋點代碼到處都是,后期難以維護等問題。

缺點:

1. 顯而易見,你會在后期維護的時候寫的懷疑人生

2. 復用性差,幾乎不能移植給其他項目

3. 工作量大,而且會越寫越多

4. 統計代碼上線之后,如果出現問題,只能后續版本迭代

5. 如果統計項目名字改變了,原來老的APP版本依舊會統計老的頁面名字

優點:

1. 如果非要寫一個其他統計無法做到的優點的話,那就是可自定義程度高吧,統計代碼想寫到那里寫到那里(其實這些也可以在后面的方案實現,只是實現上稍微麻煩一點罷了)

2. 最容易想到的方案(前期費時少,使用起來費手不費思路)

可視化埋點

就是將埋點增加和修改的工作可視化了,提升了增加和維護埋點的體驗。

該方案的具體步驟就是:

1. 從后臺獲取需要統計的地方

2. hook住需要統計的類的load方法來Method Swizzing要統計的方法

3. 上傳統計到的事件給后臺分析

用UIViewController、UIControl為例子,講解一下該方案的思路。

UIViewController PV統計,頁面的統計較為簡單,利用Method Swizzing hook 系統的viewDidLoad, 直接通過頁面名稱即可鎖定頁面的展示代碼如下:

 

  1. +(void)load {  
  2.      static dispatch_once_t onceToken;  
  3.      dispatch_once(&onceToken, ^{  
  4.      SEL originalDidLoadSelector = @selector(viewDidLoad);  
  5.      SEL swizzingDidLoadSelector = @selector(analytic_viewDidLoad);  
  6.      [MethodSwizzingTool swizzingForClass:[self class] originalSel:originalDidLoadSelector swizzingSel:swizzingDidLoadSelector];  
  7. });  
  8.  -(void)analytic_viewDidLoad { 
  9.     [self  analytic_viewDidLoad];  
  10.     //用當前類的類名作為統計頁面的標識符   
  11.     NSString * identifier = [NSString stringWithFormat:@"%@", [self class]]; 
  12.      //通過當前類名獲取PAGEPV表內的對應的頁面的pageid和pagename   
  13.      NSDictionary * dic = [[[AnalyticTool shareInstance].data objectForKey:@"PAGE"] objectForKey:identifier];  
  14.      if (dic) {  
  15.      NSString * pageid = dic[@"screenData"][@"pageid"];  
  16.      NSString * pagename = dic[@"screenData"][@"pagename"];  
  17.      [AnalyticTool upLoadScreenName:pagename withScreenID:pageid];  
  18.      } 

 

UIControl 點擊統計,主要通過hook sendAction:to:forEvent: 來實現, 其唯一標識符我們用 targetname/selector/tag來標記,具體代碼如下:

 

  1. +(void)load  
  2. {  
  3.     static dispatch_once_t onceToken;  
  4.     dispatch_once(&onceToken, ^{  
  5.     SEL originalSelector = @selector(sendAction:to:forEvent:);  
  6.     SEL swizzingSelector = @selector(analytic_sendAction:to:forEvent:);  
  7.     [MethodSwizzingTool swizzingForClass:[self class] originalSel:originalSelector swizzingSel:swizzingSelector];  
  8.     });  
  9.  
  10. -(void)analytic_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event  
  11. {  
  12.      [self analytic_sendAction:action to:target forEvent:event]; 
  13.      NSString * identifier = [NSString stringWithFormat:@"%@/%@/%ld", [target class],  
  14.      NSStringFromSelector(action),self.tag]; NSDictionary * dic = [[[AnalyticTool shareInstance].data objectForKey:@"ACTION"] objectForKey:identifier];  
  15.      if (dic) { 
  16.      NSString * eventid = dic[@"ActionData"][@"eventid"];  
  17.      NSString * targetname = dic[@"ActionData"][@"target"];  
  18.      NSString * pageid = dic[@"ActionData"][@"pageid"];  
  19.      NSString * pagename = dic[@"ActionData"][@"pagename"]; 
  20.      [AnalyticTool upLoadActionEventWithScreenName:pagename withScreenID:pageid withTargetName:targetname withEventID:eventid];  
  21.     } 

 

缺點:

1. 需要后臺配合

2. 可拓展性不是很高,因為需要修改后臺下發的統計內容來做每次的版本統計擴展

優點:

1. 相對于第一種方案,代碼量少了很多。

2. 動態化從后臺獲取統計內容,方便線上修改

無埋點

無埋點,并不是不需要埋點,而更確切地說是“全埋點”,而且埋點代碼不會出現在業務代碼中,容易管理和維護。它的缺點在于,埋點成本高,后期的解析也比較復雜,再加上 view_path 的不確定性。所以,這種方案并不能解決所有的埋點需求,但對于大量通用的埋點需求來說,能夠節省大量的開發和維護成本。

在這其中,可視化埋點和無埋點,都屬于是無侵入的埋點方案,因為它們都不需要在工程代碼中寫入埋點代碼。所以,采用這樣的無侵入埋點方案,既可以做到埋點被統一維護,又可以實現和工程代碼的解耦。

接下來,我們就通過今天這篇文章,一起來分析一下無侵入埋點方案的實現問題吧。

運行時方法替換方式進行埋點

我們都知道,在 iOS 開發中最常見的三種埋點,就是對頁面進入次數、頁面停留時間、點擊事件的埋點。對于這三種常見情況,我們都可以通過運行時方法替換技術來插入埋點代碼,以實現無侵入的埋點方法。具體的實現方法是:先寫一個運行時方法替換的類 ViewHook,加上替換的方法 hookClass:fromSelector:toSelector,代碼如下:

 

  1. #import "ViewHook.h" 
  2. #import <objc/runtime.h> 
  3.  
  4. @implementation ViewHook 
  5.  
  6. + (void)hookClass:(Class)classObject fromSelector:(SEL)fromSelector toSelector:(SEL)toSelector { 
  7.     Class class = classObject; 
  8.     // 得到被替換類的實例方法 
  9.     Method fromMethod = class_getInstanceMethod(class, fromSelector); 
  10.     // 得到替換類的實例方法 
  11.     Method toMethod = class_getInstanceMethod(class, toSelector); 
  12.      
  13.     // class_addMethod 返回成功表示被替換的方法沒實現,然后會通過 class_addMethod 方法先實現;返回失敗則表示被替換方法已存在,可以直接進行 IMP 指針交換  
  14.     if(class_addMethod(class, fromSelector, method_getImplementation(toMethod), method_getTypeEncoding(toMethod))) { 
  15.       // 進行方法的替換 
  16.         class_replaceMethod(class, toSelector, method_getImplementation(fromMethod), method_getTypeEncoding(fromMethod)); 
  17.     } else { 
  18.       // 交換 IMP 指針 
  19.         method_exchangeImplementations(fromMethod, toMethod); 
  20.     } 
  21.  
  22.  
  23. @end 

 

這個方法利用運行時method_exchangeImplementations 接口將方法的實現進行了交換,原方法調用時就會被hook 住,從而去執行指定的方法。

頁面進入次數、頁面停留時間都需要對 UIViewController 生命周期進行埋點,你可以創建一個 UIViewController 的 Category,代碼如下:

 

  1. @implementation UIViewController (logger) 
  2. + (void)load { 
  3.     static dispatch_once_t onceToken; 
  4.     dispatch_once(&onceToken, ^{ 
  5.         // 通過 @selector 獲得被替換和替換方法的 SEL,作為 ViewHook:hookClass:fromeSelector:toSelector 的參數傳入  
  6.         SEL fromSelectorAppear = @selector(viewWillAppear:); 
  7.         SEL toSelectorAppear = @selector(hook_viewWillAppear:); 
  8.         [ViewHook hookClass:self fromSelector:fromSelectorAppear toSelector:toSelectorAppear]; 
  9.          
  10.         SEL fromSelectorDisappear = @selector(viewWillDisappear:); 
  11.         SEL toSelectorDisappear = @selector(hook_viewWillDisappear:); 
  12.          
  13.         [ViewHook hookClass:self fromSelector:fromSelectorDisappear toSelector:toSelectorDisappear]; 
  14.     }); 
  15.  
  16. - (void)hook_viewWillAppear:(BOOL)animated { 
  17.     // 先執行插入代碼,再執行原 viewWillAppear 方法 
  18.     [self insertToViewWillAppear]; 
  19.     [self hook_viewWillAppear:animated]; 
  20. - (void)hook_viewWillDisappear:(BOOL)animated { 
  21.     // 執行插入代碼,再執行原 viewWillDisappear 方法 
  22.     [self insertToViewWillDisappear]; 
  23.     [self hook_viewWillDisappear:animated]; 
  24.  
  25. - (void)insertToViewWillAppear { 
  26.     // 在 ViewWillAppear 時進行日志的埋點 
  27.     [[[[SMLogger create
  28.        message:[NSString stringWithFormat:@"%@ Appear",NSStringFromClass([self class])]] 
  29.       classify:ProjectClassifyOperation] 
  30.      save]; 
  31. - (void)insertToViewWillDisappear { 
  32.     // 在 ViewWillDisappear 時進行日志的埋點 
  33.     [[[[SMLogger create
  34.        message:[NSString stringWithFormat:@"%@ Disappear",NSStringFromClass([self class])]] 
  35.       classify:ProjectClassifyOperation] 
  36.      save]; 
  37. @end 

 

可以看到,Category 在+load() 方法里使用了 ViewHook 進行方法替換,在替換的方法里執行需要埋點的方法 [self insertToViewWillAppear]。 這樣的話,每個UIViewController生命周期到了ViewWillAppear 時都會去執行insertToViewWillAppear 方法。

那么,我們要怎么區別不同的 UIViewController 呢?我一般采取的做法都是,使用NSStringFromClass([self class]) 方法來取類名。這樣,我就能夠通過類名來區別不同的 UIViewController 了。

對于點擊事件來說,我們也可以通過運行時方法替換的方式進行無侵入埋點。這里最主要的工作是,找到這個點擊事件的方法 sendAction:to:forEvent:,然后在 +load() 方法使用 ViewHook 替換成為你定義的方法。完整代碼實現如下:

 

  1. + (void)load { 
  2.     static dispatch_once_t onceToken; 
  3.     dispatch_once(&onceToken, ^{ 
  4.         // 通過 @selector 獲得被替換和替換方法的 SEL,作為 ViewHook:hookClass:fromeSelector:toSelector 的參數傳入 
  5.         SEL fromSelector = @selector(sendAction:to:forEvent:); 
  6.         SEL toSelector = @selector(hook_sendAction:to:forEvent:); 
  7.         [ViewHook hookClass:self fromSelector:fromSelector toSelector:toSelector]; 
  8.     }); 
  9.  
  10. - (void)hook_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event { 
  11.     [self insertToSendAction:action to:target forEvent:event]; 
  12.     [self hook_sendAction:action to:target forEvent:event]; 
  13. - (void)insertToSendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event { 
  14.     // 日志記錄 
  15.     if ([[[event allTouches] anyObject] phase] == UITouchPhaseEnded) { 
  16.         NSString *actionString = NSStringFromSelector(action); 
  17.         NSString *targetName = NSStringFromClass([target class]); 
  18.         [[[SMLogger create] message:[NSString stringWithFormat:@"%@ %@",targetName,actionString]] save]; 
  19.     } 

 

和 UIViewController 生命周期埋點不同的是,UIButton 在一個視圖類中可能有多個不同的繼承類,相同 UIButton 的子類在不同視圖類的埋點也要區別開。所以,我們需要通過 “action 選擇器名NSStringFromSelector(action)” +“視圖類名 NSStringFromClass([target class])”組合成一個唯一的標識,來進行埋點記錄。

除了 UIViewController、UIButton 控件以外,Cocoa 框架的其他控件都可以使用這種方法來進行無侵入埋點。以 Cocoa 框架中最復雜的 UITableView 控件為例,你可以使用 hook setDelegate 方法來實現無侵入埋點。另外,對于 Cocoa 框架中的手勢事件(Gesture Event),我們也可以通過 hook initWithTarget:action: 方法來實現無侵入埋點。

事件唯一標識

通過運行時方法替換的方式,我們能夠 hook 住所有的 Objective-C 方法,可以說是大而全了,能夠幫助我們解決絕大部分的埋點問題。

但是,這種方案的精確度還不夠高,還無法區分相同類在不同視圖樹節點的情況。比如,一個視圖下相同 UIButton 的不同實例,僅僅通過 “action 選擇器名”+“視圖類名”的組合還不能夠區分開。這時,我們就需要有一個唯一標識來區分不同的事件。接下來,我就跟你說說如何制定出這個唯一標識。

這時,我首先想到的就是,能不能通過視圖層級的路徑來解決這個問題。因為每個頁面都有一個視圖樹結構,通過視圖的 superview 和 subviews 的屬性,我們就能夠還原出每個頁面的視圖樹。視圖樹的頂層是 UIWindow,每個視圖都在樹的子節點上。如下圖所示:

一個視圖下的子節點可能是同一個視圖的不同實例,比如上圖中 UIView 視圖節點下的兩個 UIButton 是同一個類的不同實例,所以光靠視圖樹的路徑還是沒法唯一確定出視圖的標識。那么,這種情況下,我們又應該如何區別不同的視圖呢?

這時,我們想到了索引:每個子視圖在父視圖中都會有自己的索引,所以如果我們再加上這個索引的話,每個視圖的標識就是唯一的了。

接下來的一個問題是,視圖層級路徑加上在父視圖中的索引來進行唯一標識,是不是就能夠涵蓋所有情況了呢?

當然不是。我們還需要考慮類似 UITableViewCell 這種具有可復用機制的視圖,Cell 會在頁面滾動時不斷復用,所以加索引的方式還是沒法用。

但這個問題也并不是無解的。UITableViewCell 需要使用 indexPath,這個值里包含了 section 和 row 的值。所以,我們可以通過 indexPath 來確定每個 Cell 的唯一性。

除了 UITableViewCell 這種情況之外, UIAlertController 也比較特殊。它的特殊性在于視圖層級的不固定,因為它可能出現在任何頁面中。但是,我們都知道它的功能區分往往通過彈窗內容來決定,所以可以通過內容來確定它的唯一標識。

除此之外,還有更多需要特殊處理的情況,但我們總是可以通過一些辦法去確定它們的唯一性,所以我在這里也就不再一一列舉了。思路上來說就是,想辦法找出元素間不相同的因素然后進行組合,最后形成一個能夠區別于其他元素的標識來。

除了上面提到的這些特殊情況外,還有一種情況使得我們也難以得到準確的唯一標識。如果視圖層級在運行時會被更改,比如執行 insertSubView:atIndex:、removeFromSuperView 等方法時,我們也無法得到唯一標識,即使只截取部分路徑也無法保證后期代碼更新時不會動到這個部分。就算是運行時視圖層級不會修改,以后需求迭代頁面更新頻繁的話,視圖唯一標識也需要同步的更新維護。

這種問題就不好解決了,事件唯一標識的準確性難以保障,這也是通過運行時方法替換進行無侵入埋點很難在各個公司全面鋪開的原因。雖然無侵入埋點無法覆蓋到所有情況,全面鋪開面臨挑戰,但是無侵入埋點還是解決了大部分的埋點需求,也節省了大量的人力成本。

最好的方案永遠是針對于不同的場景來說的,我們不可能在一個創業團隊一開始就選擇方案3的架構,所以對于你來說,你要自己抉擇目前而言對你最好的方案,如果你沒有后臺業務同學的支持,方案1也許對你來說真的是最好的方案了,起碼是可以完成統計需求,雖然苦點累點。但是在合適的時間,切換不同的選擇,才是成長的體現,還是最開始的話,如果你在的團隊,已經給你了資源和時間去完善埋點這個模塊,如果你把它做的更好,那一定是一件很酷的事情。

參考資料

1. 網易HubbleData無痕埋點SDK實現

2. iOS無埋點數據SDK實踐之路

3. 美團前端無痕埋點方案

4. 微信讀書團隊Aspects的基本原理

5. iOS打點雜談

【本文是51CTO專欄機構“AiChinaTech”的原創文章,微信公眾號( id: tech-AI)”】

戳這里,看該作者更多好文 

 

責任編輯:華軒 來源: 51CTO專欄
相關推薦

2021-08-10 13:50:24

iOS

2023-12-13 18:46:50

FlutterAOP業務層

2016-12-12 13:42:54

數據分析大數據埋點

2021-02-19 07:59:21

數據埋點數據分析大數據

2024-09-06 07:55:42

2023-09-05 07:28:02

Java自動埋點

2023-04-19 09:05:44

2017-12-28 14:54:04

Android代碼埋點全埋點

2021-12-26 23:34:00

微服務Istio壓縮

2022-08-31 07:54:08

采集sdk埋點數據

2023-02-06 07:47:23

2025-07-11 09:09:00

2024-07-18 08:33:19

2023-01-10 09:08:53

埋點數據數據處理

2019-08-12 10:45:54

Flutter框架Native

2019-08-14 15:08:51

緩存存儲數據

2019-11-11 15:33:34

高并發緩存數據

2024-11-01 12:39:04

2025-11-06 01:45:00

2025-07-03 03:20:00

點贊
收藏

51CTO技術棧公眾號

91精品国产综合久久香蕉922| 亚洲二区中文字幕| 欧美性受xxxx黑人猛交88| 性生交大片免费看女人按摩| 国产免费成人| 久久精品2019中文字幕| 日本69式三人交| 成人在线高清| 亚洲va在线va天堂| 一区二区冒白浆视频| 可以免费看毛片的网站| 免费看日韩精品| 久久久噜久噜久久综合| 超碰97av在线| 亚洲另类av| 日韩美女天天操| 在线看的黄色网址| 在线看的毛片| 亚洲综合无码一区二区| 亚洲国产欧美日韩| 三级视频在线| 国产sm精品调教视频网站| 国产欧美一区二区三区在线| 6080午夜伦理| 亚洲黄色大片| 九九九久久国产免费| 中文字幕有码在线播放| 欧美日韩看看2015永久免费| 日韩三级在线观看| а 天堂 在线| 国产精品美女午夜爽爽| 色婷婷亚洲精品| 欧洲精品一区二区三区久久| 国产精品va在线观看视色| 中文字幕av资源一区| 欧美福利精品| 亚洲欧洲国产综合| www.亚洲免费av| 999精品在线观看| 国产日韩免费视频| 久久er精品视频| 国产精品稀缺呦系列在线| youjizz在线视频| 亚洲影音先锋| 91高清视频免费观看| 日韩免费黄色片| 韩日欧美一区| 久久久亚洲国产| 国产一级在线免费观看| 国产综合亚洲精品一区二| 欧美xxxx18性欧美| 久久久久久免费观看| 女人香蕉久久**毛片精品| 久久精品一本久久99精品| 国产三级精品三级观看| 色综合久久网| 久久精品国产电影| 国产av无码专区亚洲av毛网站| 97色伦图片97综合影院| 久久精品小视频| 国产午夜手机精彩视频| 欧美日韩视频| 国外成人性视频| 久久久午夜影院| 欧美资源在线| 国产精品亚洲欧美导航| 国产巨乳在线观看| 高清不卡在线观看av| 国产欧美日韩视频一区二区三区| 天堂8在线视频| 久久众筹精品私拍模特| 色狠狠久久av五月综合| 欧美成人二区| 一区二区三区91| 777久久久精品一区二区三区 | 亚洲综合精品国产一区二区三区 | 一区二区高清不卡| **性色生活片久久毛片| 国产免费裸体视频| 亚洲性受xxx喷奶水| 91精品办公室少妇高潮对白| 国产原创精品在线| 北条麻妃一区二区三区在线| 国产婷婷97碰碰久久人人蜜臀| 亚洲黄色小说视频| 在线精品国产| 欧美有码在线视频| 一级特黄色大片| 成人福利电影精品一区二区在线观看| 麻豆av一区二区三区久久| 视频免费一区| 午夜国产不卡在线观看视频| 99热这里只有精品在线播放| aaa国产精品| 亚洲人成网在线播放| 男女做暖暖视频| 欧美亚洲自偷自偷| 亚洲精品免费网站| 九色国产在线观看| 亚洲卡通动漫在线| 日韩精品一区二区三区不卡| 另类视频一区二区三区| 亚洲欧美中文字幕在线一区| 国产精品99久久久久久成人| 在线视频亚洲| 亚洲va久久久噜噜噜| 青青青草原在线| 亚洲综合视频在线| 在线观看免费av网址| 婷婷精品在线观看| 欧美wwwxxxx| 欧美日韩 一区二区三区| 成人中文字幕合集| 免费久久久久久| 日韩欧美一区二区三区在线观看| 亚洲成人精品视频在线观看| 午夜成人亚洲理伦片在线观看| 亚洲欧美高清| 国产日韩一区欧美| 影音先锋在线播放| 欧美巨大另类极品videosbest | 最近中文字幕一区二区三区| 久草资源站在线观看| 99精品中文字幕在线不卡| 精品久久国产精品| 一本到在线视频| 欧美激情综合在线| 116极品美女午夜一级| 99re热精品视频| 欧美成人一区二区三区电影| 自拍偷拍色综合| 久久久久国产成人精品亚洲午夜| 美女日批免费视频| 国产精品天天看天天狠| 久久99热这里只有精品国产| 99精品在线视频观看| 国产精品久久久一本精品| 激情五月开心婷婷| 西野翔中文久久精品国产| 国外成人在线直播| 天堂在线视频免费| 精品久久久久久亚洲国产300 | av免费观看在线| 亚洲日本欧美天堂| 亚洲一区二区图片| 你懂的亚洲视频| 99re在线观看视频| av小说在线播放| 亚洲成色999久久网站| 国产在线视频在线观看| 国产aⅴ精品一区二区三区色成熟| 无码毛片aaa在线| 亚洲精品黑牛一区二区三区| 欧美国产日韩一区二区| 好吊视频一区二区三区| 午夜伊人狠狠久久| 精品夜夜澡人妻无码av| 天堂久久久久va久久久久| 日韩欧美电影一区二区| 高清不卡亚洲| 最近2019中文字幕一页二页| 一级特黄aaa大片| 亚洲精品国产品国语在线app| 日韩高清一二三区| 亚洲一区图片| 亚洲欧美精品在线观看| 久久av网站| 韩国视频理论视频久久| 美国一级片在线免费观看视频| 欧亚洲嫩模精品一区三区| 午夜国产小视频| 成人自拍视频在线观看| 日本xxxxxxx免费视频| 欧美日韩一二三四| 亚洲综合国产精品| 美女高潮在线观看| 欧美深性狂猛ⅹxxx深喉| 麻豆视频在线看| 亚洲欧美福利视频| 国产又粗又猛又黄视频| 国产精品久久久久久久久久免费看| 91丨九色丨蝌蚪| 欧美日韩爆操| 欧美日韩国产高清视频| 四虎地址8848精品| 午夜精品一区二区三区在线| 欧美一区二区视频| 欧美美女一区二区三区| 黄色小说在线观看视频| 久久久久久久综合日本| 天堂av2020| 亚洲国产免费| 翔田千里亚洲一二三区| 亚洲乱码一区| 国产精品久久一区| 国产理论电影在线| 一区二区三区在线播放欧美| www.黄色片| 日本韩国一区二区三区| 久久国产精品波多野结衣| 久久亚洲精品国产精品紫薇| 男女污污视频网站| 久久午夜精品一区二区| av影院在线播放| av一区二区高清| 精品一区二区国产| 国产精品视频一区二区三区综合| 欧美一区在线直播| 人人超在线公开视频| 中文字幕亚洲第一| 天天操天天操天天干| 制服丝袜国产精品| 精品久久久久久久久久久久久久久久| 亚洲卡通动漫在线| 日本成人免费在线观看| 97精品国产露脸对白| 超碰91在线播放| 久久99精品一区二区三区三区| 成人综合视频在线| 亚洲激情视频| 好吊色视频988gao在线观看| 人人狠狠综合久久亚洲婷| 免费国产一区| 老牛影视av一区二区在线观看| 5g国产欧美日韩视频| 久久国产三级| 国产精品久久久久久婷婷天堂| 国产色播av在线| 欧美激情一区二区三级高清视频| 69成人在线| 久久精品亚洲热| 黄色网页在线免费观看| 最好看的2019的中文字幕视频| 国产三级在线免费| 亚洲美女视频网站| 天堂√在线中文官网在线| 亚洲成年网站在线观看| www.色视频| 91精品国产欧美日韩| 97超碰资源站| 51精品视频一区二区三区| 在线播放一级片| 欧美日韩一区高清| 亚洲性在线观看| 欧美日韩精品一区二区三区四区 | eeuss影院www在线播放| 亚洲欧美日韩直播| 美丽的姑娘在线观看免费动漫| 国产午夜精品麻豆| 蜜桃视频在线入口www| 亚洲欧美日韩网| 搞黄视频在线观看| 中文字幕在线成人| 国产最新在线| 精品自拍视频在线观看| 波多野结衣中文字幕久久| 久久久久久12| 偷拍自拍在线看| 国产精品福利在线观看网址| 91欧美精品| 国产在线视频不卡| 亚洲天堂av资源在线观看| 国产精品yjizz| 少妇高潮一区二区三区| 欧美18视频| 大色综合视频网站在线播放| 伊人久久大香线蕉成人综合网| 天天综合一区| 国产精品videossex国产高清| 亚洲精品欧美| 男女啪啪网站视频| 韩国三级在线一区| 三上悠亚 电影| 91色porny在线视频| 国产亚洲精品精品精品| 亚洲男女毛片无遮挡| 亚洲欧美在线观看视频| 在线日韩av片| 精品人妻无码一区二区 | 日本免费在线观看| 欧美日韩成人在线观看| av综合电影网站| 国产在线播放不卡| 国产精品欧美大片| 午夜精品一区二区在线观看的| 一区二区三区午夜探花| 亚洲熟妇无码一区二区三区| 青青草原综合久久大伊人精品优势| 自拍一级黄色片| 久久久久久99精品| 成年人av电影| 欧洲色大大久久| 成人乱码一区二区三区| 亚洲最新中文字幕| 欧美黑人猛交的在线视频| 国产成人精品视| 1313精品午夜理伦电影| 日本免费一区二区三区| 国产一区欧美| 天堂一区在线观看| 99久久久国产精品| 中文字幕乱码av| 欧美视频专区一二在线观看| 国产又粗又黄又爽的视频| 亚洲加勒比久久88色综合| 黄色在线视频网站| 日韩av手机在线| 超碰在线成人| 在线综合视频网站| 三级欧美韩日大片在线看| aaaaa黄色片| 国产精品久99| 国产中文字幕视频| 亚洲大尺度美女在线| 黄色免费在线观看网站| 国产成人精品a视频一区www| 国产无遮挡裸体免费久久| 午夜探花在线观看| 日本视频在线一区| 亚洲一级中文字幕| 亚洲国产精品久久久久婷婷884| 91欧美日韩麻豆精品| 亚洲无限av看| 91久久国产综合久久91猫猫| 肥熟一91porny丨九色丨| 亚洲成人一区| 在线观看国产一级片| 国产日产欧美一区二区视频| 男女视频免费看| 欧美精品一区二| 国产精品国精产品一二| 亚洲wwwav| 五月久久久综合一区二区小说| 亚洲色图久久久| 久久久www成人免费无遮挡大片| 国产第一页在线播放| 日韩欧美亚洲一区二区| 成人短视频在线| 91九色精品视频| 51精产品一区一区三区| 日本国产一级片| 综合久久久久久| 99热这里只有精品5| 久久av在线播放| 精品中文在线| 17c丨国产丨精品视频| 国产成人一级电影| 国产一级片久久| 亚洲大胆美女视频| 中文字幕在线看片| 欧美一区二区视频在线| 日本欧洲一区二区| gv天堂gv无码男同在线观看| 欧美日韩精品一区二区三区| 3d成人动漫在线| 91精品视频在线看| 欧美精品97| 在线免费看黄色片| 黑人精品xxx一区一二区| 欧美色视频免费| 国产精品狠色婷| 国产精品国产三级国产在线观看| 欧美国产日韩在线视频| 亚洲一区二区在线观看视频 | 2020国产精品| 久久精品偷拍视频| 久久五月情影视| av在线亚洲色图| 国产av无码专区亚洲精品| 日本一区二区三区视频视频| 一区二区三区精| 欧美国产乱视频| 国产成人三级| 亚洲欧美天堂在线| 亚洲第一精品在线| 狠狠色伊人亚洲综合网站l| 国产欧美日韩精品在线观看 | 久久久久久久久久久国产| 在线亚洲a色| 小早川怜子一区二区三区| 午夜欧美一区二区三区在线播放| 成人在线免费看| 亚洲综合最新在线| 午夜亚洲一区| 手机av在线看| 日韩av中文在线| 国产a亚洲精品| 久久精品无码中文字幕| 国产日韩精品一区二区三区| 99精品人妻无码专区在线视频区| 欧美夜福利tv在线| 天天综合久久| 蜜桃精品一区二区| 日韩限制级电影在线观看| 新片速递亚洲合集欧美合集| 日本a在线天堂| 国产精品色哟哟| 五月激情六月婷婷| 成人免费午夜电影| 香蕉精品999视频一区二区|