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

首頁 > 系統 > iOS > 正文

ios實現搜索關鍵字高亮效果

2020-07-26 02:30:45
字體:
來源:轉載
供稿:網友

一. 需求要求實現的效果

漢字支持漢字直接搜索、拼音全拼搜索、拼音簡拼搜索

搜索匹配到的關鍵字高亮顯示

搜索結果優先顯示全部匹配、其次是拼音全拼匹配、拼音簡拼匹配;關鍵字在結果字符串中位置越靠前,優先顯示

支持搜索英文、漢字、電話號碼及混合搜索

二. 需求分析

英文名稱及電話號碼的搜索直接使用完全匹配的方式即可

重難點是漢字的拼音相關的拼音全拼、簡拼搜索,比如 “劉亦菲” 對應的搜索關鍵字有且只有以下三大類總計 25 種匹配漢字:“劉”、“亦”、“菲”、“劉亦”、“亦菲”、“劉亦菲”

簡拼相關:"l"、"y"、"f"、"ly"、"yf"、"lyf"

全拼相關:"li"、"liu"、"liuy"、"liuyi"、"liuyif"、"liuyife"、"liuyifei"、"yi"、"yif"、"yife"、"yifei"、"fe"、"fei"

拼音的重難點還包括:比如搜索關鍵字為“xian”,既要匹配出“先”,也要匹配出“西安”

三. 代碼設計

1. 整體流程

首先初始化原始的數據(包含漢語、英文、數字及隨意組合),主要是將一個漢語字符串轉化為漢語全拼拼音及每個拼音字母所對應漢字的位置 和 漢語簡拼拼音和每個拼音字母對應漢字的位置,將初始化之后的信息緩存起來

+ (instancetype)personWithName:(NSString *)name hanyuPinyinOutputFormat:(HanyuPinyinOutputFormat *)pinyinFormat { WPFPerson *person = [[WPFPerson alloc] init];  /** 將漢字轉化為拼音的類方法  * name : 需要轉換的漢字  * pinyinFormat : 拼音的格式化器  * @"" : seperator 分隔符  */ NSString *completeSpelling = [PinyinHelper toHanyuPinyinStringWithNSString:name withHanyuPinyinOutputFormat:pinyinFormat withNSString:@""];  // 首字母所組成的字符串 NSString *initialString = @""; // 全拼拼音數組 NSMutableArray *completeSpellingArray = [[NSMutableArray alloc] init]; // 拼音首字母的位置數組 NSMutableArray *pinyinFirstLetterLocationArray = [[NSMutableArray alloc] init];  // 遍歷每一個字符 for (NSInteger x =0; x根據 UISearchResultsUpdating 代理方法 - (void)updateSearchResultsForSearchController:(UISearchController *)searchController 來實時獲取輸入的最新關鍵字,并遍歷數據源,將匹配到的結果顯示出來// 更新搜索結果- (void)updateSearchResultsForSearchController:(UISearchController *)searchController { NSLog(@"%@", searchController.searchBar.text);  [self.searchResultVC.resultDataSource removeAllObjects];  for (WPFPerson *person in self.dataSource) {  WPFSearchResultModel *resultModel = [WPFPinYinTools            searchEffectiveResultWithSearchString:searchController.searchBar.text.lowercaseString            nameString:person.name            completeSpelling:person.completeSpelling            initialString:person.initialString            pinyinLocationString:person.pinyinLocationString            initialLocationString:person.initialLocationString];    if (resultModel.highlightRang.length) {   person.highlightLoaction = resultModel.highlightRang.location;   person.textRange = resultModel.highlightRang;   person.matchType = resultModel.matchType;   [self.searchResultVC.resultDataSource addObject:person];  } }; // 將匹配結果按照產品規則進行排序 [self.searchResultVC.resultDataSource sortUsingDescriptors:[WPFPinYinTools sortingRules]]; // 刷新tableView dispatch_async(dispatch_get_main_queue(), ^{  [self.searchResultVC.tableView reloadData]; });}

匹配的過程是一個重難點,分別進行漢字直接匹配、拼音全拼匹配、拼音簡拼匹配

+ (WPFSearchResultModel *)searchEffectiveResultWithSearchString:(NSString *)searchStrLower              nameString:(NSString *)nameStrLower            completeSpelling:(NSString *)completeSpelling             initialString:(NSString *)initialString           pinyinLocationString:(NSString *)pinyinLocationString           initialLocationString:(NSString *)initialLocationString {  WPFSearchResultModel *searchModel = [[WPFSearchResultModel alloc] init];  NSArray *completeSpellingArray = [pinyinLocationString componentsSeparatedByString:@","]; NSArray *pinyinFirstLetterLocationArray = [initialLocationString componentsSeparatedByString:@","];  // 完全中文匹配范圍 NSRange chineseRange = [nameStrLower rangeOfString:searchStrLower]; // 拼音全拼匹配范圍 NSRange complateRange = [completeSpelling rangeOfString:searchStrLower]; // 拼音首字母匹配范圍 NSRange initialRange = [initialString rangeOfString:searchStrLower];  // 漢字直接匹配 if (chineseRange.length!=0) {  searchModel.highlightedRange = chineseRange;  searchModel.matchType = MatchTypeChinese;  return searchModel; }  NSRange highlightedRange = NSMakeRange(0, 0);  // MARK: 拼音全拼匹配 if (complateRange.length != 0) {  if (complateRange.location == 0) {   // 拼音首字母匹配從0開始,即搜索的關鍵字與該數據源第一個漢字匹配到,所以高亮范圍從0開始   highlightedRange = NSMakeRange(0, [completeSpellingArray[complateRange.length-1] integerValue] +1);     } else {   /** 如果該拼音字符是一個漢字的首個字符,如搜索“g”,    * 就要匹配出“gai”、“ge”等“g”開頭的拼音對應的字符,    * 而不應該匹配到“wang”、“feng”等非”g“開頭的拼音對應的字符    */   NSInteger currentLocation = [completeSpellingArray[complateRange.location] integerValue];   NSInteger lastLocation = [completeSpellingArray[complateRange.location-1] integerValue];   if (currentLocation != lastLocation) {    // 高亮范圍從匹配到的第一個關鍵字開始    highlightedRange = NSMakeRange(currentLocation, [completeSpellingArray[complateRange.length+complateRange.location -1] integerValue] - currentLocation +1);   }  }  searchModel.highlightedRange = highlightedRange;  searchModel.matchType = MatchTypeComplate;  if (highlightedRange.length!=0) {   return searchModel;  } }  // MARK: 拼音首字母匹配 if (initialRange.length!=0) {  NSInteger currentLocation = [pinyinFirstLetterLocationArray[initialRange.location] integerValue];  NSInteger highlightedLength;  if (initialRange.location ==0) {   highlightedLength = [pinyinFirstLetterLocationArray[initialRange.length-1] integerValue]-currentLocation +1;   // 拼音首字母匹配從0開始,即搜索的關鍵字與該數據源第一個漢字匹配到,所以高亮范圍從0開始   highlightedRange = NSMakeRange(0, highlightedLength);  } else {   highlightedLength = [pinyinFirstLetterLocationArray[initialRange.length+initialRange.location-1] integerValue]-currentLocation +1;   // 高亮范圍從匹配到的第一個關鍵字開始   highlightedRange = NSMakeRange(currentLocation, highlightedLength);  }  searchModel.highlightedRange = highlightedRange;  searchModel.matchType = MatchTypeInitial;  if (highlightedRange.length!=0) {   return searchModel;  } } searchModel.highlightedRange = NSMakeRange(0, 0); searchModel.matchType = NSIntegerMax; return searchModel;}

2. 第三方依賴

首先篩選出一個比較全的第三方庫 PinYin4Objc用于漢語轉拼音,拼音的 unicode 庫比較全,一些新的漢字也都能轉成拼音
但是由于該庫好久沒有更新,獲取拼音文件部分代碼不適合組件化的直接開發,因此我直接合到源文件里面了
漢語轉拼音的格式

// 獲取格式化器+ (HanyuPinyinOutputFormat *)getOutputFormat { HanyuPinyinOutputFormat *pinyinFormat = [[HanyuPinyinOutputFormat alloc] init]; /** 設置大小寫  * CaseTypeLowercase : 小寫  * CaseTypeUppercase : 大寫  */ [pinyinFormat setCaseType:CaseTypeLowercase]; /** 聲調格式 :如 王鵬飛  * ToneTypeWithToneNumber : 用數字表示聲調 wang2 peng2 fei1  * ToneTypeWithoutTone : 無聲調表示 wang peng fei  * ToneTypeWithToneMark : 用字符表示聲調 wáng péng fēi  */ [pinyinFormat setToneType:ToneTypeWithoutTone]; /** 設置特殊拼音ü的顯示格式:  * VCharTypeWithUAndColon : 以U和一個冒號表示該拼音,例如:lu:  * VCharTypeWithV   : 以V表示該字符,例如:lv  * VCharTypeWithUUnicode : 以ü表示  */ [pinyinFormat setVCharType:VCharTypeWithV]; return pinyinFormat;}

3. 其他細節

排序規則

+ (NSArray *)sortingRules { // 按照 matchType 順序排列,即優先展示 中文,其次是全拼匹配,最后是拼音首字母匹配 NSSortDescriptor *desType = [NSSortDescriptor sortDescriptorWithKey:@"matchType" ascending:YES]; // 優先顯示 高亮位置索引靠前的搜索結果 NSSortDescriptor *desLocation = [NSSortDescriptor sortDescriptorWithKey:@"highlightLoaction" ascending:YES]; return @[desType,desLocation];}

四. 循環方法測試及優化選擇過程

在優化遍歷方法的過程中,測試了幾種遍歷方法,這里以輸入關鍵字“wang”為測試數據,測試真機機型為iPhone SE 10.3

常規 for 循環

/** 2017-12-06 12:02:51.943006 HighlightedSearch[4459:1871193] w 2017-12-06 12:02:51.943431 HighlightedSearch[4459:1871193] 開始匹配,開始時間:2017-12-06 04:02:51 +0000 2017-12-06 12:02:51.980588 HighlightedSearch[4459:1871193] 匹配結束,結束時間:2017-12-06 04:02:51 +0000,耗時:0.0372 2017-12-06 12:02:52.284488 HighlightedSearch[4459:1871193] wa 2017-12-06 12:02:52.284771 HighlightedSearch[4459:1871193] 開始匹配,開始時間:2017-12-06 04:02:52 +0000 2017-12-06 12:02:52.316536 HighlightedSearch[4459:1871193] 匹配結束,結束時間:2017-12-06 04:02:52 +0000,耗時:0.0318 2017-12-06 12:02:52.516826 HighlightedSearch[4459:1871193] wan 2017-12-06 12:02:52.517121 HighlightedSearch[4459:1871193] 開始匹配,開始時間:2017-12-06 04:02:52 +0000 2017-12-06 12:02:52.545542 HighlightedSearch[4459:1871193] 匹配結束,結束時間:2017-12-06 04:02:52 +0000,耗時:0.0285 2017-12-06 12:02:52.838220 HighlightedSearch[4459:1871193] wang 2017-12-06 12:02:52.838602 HighlightedSearch[4459:1871193] 開始匹配,開始時間:2017-12-06 04:02:52 +0000 2017-12-06 12:02:52.880200 HighlightedSearch[4459:1871193] 匹配結束,結束時間:2017-12-06 04:02:52 +0000,耗時:0.0417 */for (NSInteger i = 0; i < self.dataSource.count; i++) {

GCD 多線程循環

/** 2017-12-06 11:56:55.565738 HighlightedSearch[4419:1869486] w 2017-12-06 11:56:55.566287 HighlightedSearch[4419:1869486] 開始匹配,開始時間:2017-12-06 03:56:55 +0000 2017-12-06 11:56:55.626184 HighlightedSearch[4419:1869486] 匹配結束,結束時間:2017-12-06 03:56:55 +0000,耗時:0.0601 2017-12-06 11:56:55.937535 HighlightedSearch[4419:1869486] wa 2017-12-06 11:56:55.937842 HighlightedSearch[4419:1869486] 開始匹配,開始時間:2017-12-06 03:56:55 +0000 2017-12-06 11:56:55.983074 HighlightedSearch[4419:1869486] 匹配結束,結束時間:2017-12-06 03:56:55 +0000,耗時:0.0452 2017-12-06 11:56:56.344808 HighlightedSearch[4419:1869486] wan 2017-12-06 11:56:56.347350 HighlightedSearch[4419:1869486] 開始匹配,開始時間:2017-12-06 03:56:56 +0000 2017-12-06 11:56:56.414215 HighlightedSearch[4419:1869486] 匹配結束,結束時間:2017-12-06 03:56:56 +0000,耗時:0.0690 2017-12-06 11:56:56.711174 HighlightedSearch[4419:1869486] wang 2017-12-06 11:56:56.712013 HighlightedSearch[4419:1869486] 開始匹配,開始時間:2017-12-06 03:56:56 +0000 2017-12-06 11:56:56.774761 HighlightedSearch[4419:1869486] 匹配結束,結束時間:2017-12-06 03:56:56 +0000,耗時:0.0632 */dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_apply(self.dataSource.count, queue, ^(size_t index) {

enumerateObjectsWithOptions 多線程循環

/** 2017-12-06 11:58:12.716606 HighlightedSearch[4428:1869917] w 2017-12-06 11:58:12.717005 HighlightedSearch[4428:1869917] 開始匹配,開始時間:2017-12-06 03:58:12 +0000 2017-12-06 11:58:12.780168 HighlightedSearch[4428:1869917] 匹配結束,結束時間:2017-12-06 03:58:12 +0000,耗時:0.0633 2017-12-06 11:58:13.058590 HighlightedSearch[4428:1869917] wa 2017-12-06 11:58:13.058841 HighlightedSearch[4428:1869917] 開始匹配,開始時間:2017-12-06 03:58:13 +0000 2017-12-06 11:58:13.116964 HighlightedSearch[4428:1869917] 匹配結束,結束時間:2017-12-06 03:58:13 +0000,耗時:0.0581 2017-12-06 11:58:13.397052 HighlightedSearch[4428:1869917] wan 2017-12-06 11:58:13.397338 HighlightedSearch[4428:1869917] 開始匹配,開始時間:2017-12-06 03:58:13 +0000 2017-12-06 11:58:13.460298 HighlightedSearch[4428:1869917] 匹配結束,結束時間:2017-12-06 03:58:13 +0000,耗時:0.0630 2017-12-06 11:58:13.763888 HighlightedSearch[4428:1869917] wang 2017-12-06 11:58:13.764263 HighlightedSearch[4428:1869917] 開始匹配,開始時間:2017-12-06 03:58:13 +0000 2017-12-06 11:58:13.833888 HighlightedSearch[4428:1869917] 匹配結束,結束時間:2017-12-06 03:58:13 +0000,耗時:0.0697 */dispatch_queue_t queue = dispatch_queue_create("wpf.updateSearchResults.test", DISPATCH_QUEUE_SERIAL);[self.dataSource enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

forin 循環

/** 2017-12-06 12:00:38.217187 HighlightedSearch[4439:1870645] w 2017-12-06 12:00:38.217575 HighlightedSearch[4439:1870645] 開始匹配,開始時間:2017-12-06 04:00:38 +0000 2017-12-06 12:00:38.253997 HighlightedSearch[4439:1870645] 匹配結束,結束時間:2017-12-06 04:00:38 +0000,耗時:0.0364 2017-12-06 12:00:38.616430 HighlightedSearch[4439:1870645] wa 2017-12-06 12:00:38.616807 HighlightedSearch[4439:1870645] 開始匹配,開始時間:2017-12-06 04:00:38 +0000 2017-12-06 12:00:38.654969 HighlightedSearch[4439:1870645] 匹配結束,結束時間:2017-12-06 04:00:38 +0000,耗時:0.0383 2017-12-06 12:00:38.948700 HighlightedSearch[4439:1870645] wan 2017-12-06 12:00:38.949453 HighlightedSearch[4439:1870645] 開始匹配,開始時間:2017-12-06 04:00:38 +0000 2017-12-06 12:00:38.986892 HighlightedSearch[4439:1870645] 匹配結束,結束時間:2017-12-06 04:00:38 +0000,耗時:0.0378 2017-12-06 12:00:39.280979 HighlightedSearch[4439:1870645] wang 2017-12-06 12:00:39.281563 HighlightedSearch[4439:1870645] 開始匹配,開始時間:2017-12-06 04:00:39 +0000 2017-12-06 12:00:39.317743 HighlightedSearch[4439:1870645] 匹配結束,結束時間:2017-12-06 04:00:39 +0000,耗時:0.0365 */for (WPFPerson *person in self.dataSource) {

最終選擇的是forin循環,因為一般情況下 enumerateObjectsWithOptions 多線程是最快的,并且稍快于 dispatch_apply 方法,但是因為這個方法需要操作數組,因此必須將操作數據的那行代碼加鎖或者在指定線程進行,進行這個操作后效率反而不如其他單線程循環,考慮到搜索結果本來還要再次根據規則排序,就選擇了 forin 循環

五. 為什么沒有選擇hash

首先最重要的一條是當前循環的方式也能滿足需求(線上大概四千多條數據,使用過程中基本實時展現)

上文在需求分析中已舉例,一個三個字的漢字對應的key值就有20多個甚至更多,在解析過程中是十分耗時的,但需求往往還存在類似微信的“群名稱”匹配,每多一個字,對應的key值就多幾個數量級

MapTable在高并發情況下,需要不斷進行Resize(擴容 & Rehash),并且在Rehash 并發的情況下還可能形成鏈表環有個優化的思路,考慮到遍歷的方式解析快,搜索匹配慢;hash的方式解析慢,搜索匹配快

通過遍歷的方式先快速解析數據,此時搜索使用遍歷的方式

然后再用hash的方式再次解析數據(考慮到hash表的擴容會使得瞬時效率的降低,為了避免頻繁的擴容,先使用桶排序的方法將10個數字、26個英文字母、以及特殊符號開頭的key分別放在37個字典里面,整體是一個數組。每個字典里面存放對應key和value),解析完成之后做個標記就采用hash的方式直接使用輸入的key值去查詢

配合DB緩存,效果應該是很棒的

六. 多音字

簡單測了一下擁有該功能的產品:

微信搜索(就是文中講的該類型搜索)是在本地做的,不支持多音字

釘釘的搜索是服務器做的,支持多音字(但是簡單測了一下一些基本的多音字存在bug)

七. 實際項目還要做哪些工作?

正常情況下不會將所有的匹配結果在第一時間全部顯示,一般產品需求顯示三五個即可,因此可以匹配出若干個結果后停止循環,點擊更多再匹配剩余數據源

配合DB和hashTable,每次只解析新增的數據源,解析一次后就緩存起來

八. 使用方法

1. 事例工程

git clone git@github.com:PengfeiWang666/HighlightedSearch.gitcd Exampleopen HighlightedSearch.xcworkspace

2. Install

pod "HighlightedSearch"

3. Usage

// WPFPinYinDataManager 依次添加數據源(標識符為了防止重名現象)+ (void)addInitializeString:(NSString *)string identifer:(NSString *)identifier// 更新搜索結果- (void)updateSearchResultsForSearchController:(UISearchController *)searchController { ... ... for (WPFPerson *person in [WPFPinYinDataManager getInitializedDataSource]) {  WPFSearchResultModel *resultModel = [WPFPinYinTools searchEffectiveResultWithSearchString:keyWord Person:person];  if (resultModel.highlightedRange.length) {   person.highlightLoaction = resultModel.highlightedRange.location;   person.textRange = resultModel.highlightedRange;   person.matchType = resultModel.matchType;    [resultDataSource addObject:person];  }}

最后附上源碼:https://github.com/PengfeiWang666/HighlightedSearch

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲在线免费看| 成人午夜激情免费视频| 欧美午夜精品久久久久久久| 性色av香蕉一区二区| 91精品国产电影| 欧美精品情趣视频| 亚洲一区二区久久| 精品国产乱码久久久久酒店| 精品国产欧美成人夜夜嗨| 久久久精品一区| 日韩精品一二三四区| 日韩黄在线观看| 国产精品久久久久高潮| 大胆人体色综合| 国产在线一区二区三区| 欧美在线视频一区二区| 欧美一级片在线播放| 91最新在线免费观看| 久久6精品影院| 亚洲成人激情在线观看| 亚洲一级黄色av| 97久久超碰福利国产精品…| 久久婷婷国产麻豆91天堂| 亚洲资源在线看| 亚洲色图偷窥自拍| 欧美激情一区二区三级高清视频| 亚洲国产欧美精品| 亚洲视频axxx| 欧美成人免费全部观看天天性色| 中文欧美在线视频| 欧美激情亚洲一区| 亚洲永久在线观看| 欧美成年人视频| 亚洲第一男人av| 国产精品久久久久一区二区| 国产91ⅴ在线精品免费观看| 8050国产精品久久久久久| 日韩一中文字幕| 国产欧美亚洲视频| 91久久精品美女| 欧美怡春院一区二区三区| 国产自产女人91一区在线观看| 日韩精品久久久久久福利| 亚洲第一精品夜夜躁人人爽| 亚洲xxxxx电影| 美女啪啪无遮挡免费久久网站| 国产成人精品a视频一区www| 亚州av一区二区| 国产精品视频99| 国产精品久久久av| 亚洲福利在线播放| 欧美激情一区二区三区久久久| 欧美亚洲午夜视频在线观看| 亚洲国产成人精品女人久久久| 亚洲成人精品视频在线观看| 欧美激情va永久在线播放| 黑人巨大精品欧美一区二区三区| 精品小视频在线| 亚洲影院高清在线| 亲爱的老师9免费观看全集电视剧| 精品久久久久久中文字幕| 日韩精品欧美激情| 深夜福利国产精品| 亲子乱一区二区三区电影| 国产欧美日韩中文字幕在线| 日本人成精品视频在线| 一区二区三区久久精品| 亚洲成年网站在线观看| 尤物精品国产第一福利三区| 91在线免费视频| 欧美激情欧美激情在线五月| 色综合伊人色综合网站| 亚洲精品电影网站| 亚洲人线精品午夜| 欧美国产日韩在线| 欧美成人精品xxx| 国产精品va在线播放| 亚洲第一精品久久忘忧草社区| 欧美尺度大的性做爰视频| 国产精品都在这里| 日韩理论片久久| 91高清视频在线免费观看| 久久久免费观看| 国产一区红桃视频| 国产精品久久久久久久久男| 国内精品400部情侣激情| 亚洲成人在线视频播放| 97在线精品国自产拍中文| 色综合五月天导航| 日韩av一区在线| 91大神福利视频在线| 狠狠色香婷婷久久亚洲精品| 91精品国产高清自在线看超| 亚洲色图国产精品| 亚洲国产精品一区二区久| 欧美成人亚洲成人日韩成人| 国产亚洲一区二区在线| 91视频免费网站| 国产精品自产拍在线观看中文| 亚洲a级在线播放观看| 色av中文字幕一区| 日韩av在线精品| 久久精品91久久久久久再现| 中文字幕成人在线| 国产精品免费福利| 亚洲第一精品久久忘忧草社区| 国产成人一区二区三区小说| 国产一区香蕉久久| 久久综合久久美利坚合众国| 国产成人精品一区二区三区| 欧美另类69精品久久久久9999| 欧美成人免费视频| 精品久久久一区二区| 国产精品免费久久久久影院| 欧美有码在线观看| 国产精品第3页| 久久久精品2019中文字幕神马| 亚洲第一精品自拍| 亚洲一区二区中文| 性色av一区二区三区红粉影视| 欧洲中文字幕国产精品| 成人亲热视频网站| 97国产精品人人爽人人做| 亚洲精品国产综合久久| 欧美一级在线播放| 久久不射热爱视频精品| 国产精品精品视频一区二区三区| 欧美日韩免费区域视频在线观看| 亚洲另类激情图| 欧美大肥婆大肥bbbbb| 狠狠躁夜夜躁久久躁别揉| 国产999精品| 国产日韩欧美黄色| 久久久久久国产精品美女| 久久精品久久久久久| 亚洲女人天堂成人av在线| 欧美极品美女电影一区| 日本不卡视频在线播放| 中文字幕亚洲专区| 欧美大全免费观看电视剧大泉洋| 欧美中文字幕在线| 精品福利樱桃av导航| 91成人精品网站| 国产+成+人+亚洲欧洲| 色哟哟亚洲精品一区二区| 国产精品黄色影片导航在线观看| 久久国产精品久久久久久久久久| 国产精品一二三视频| 国产成人avxxxxx在线看| 久操成人在线视频| 亚洲欧洲免费视频| 欧美色xxxx| 日韩激情第一页| 亚洲精品国精品久久99热| 亚洲级视频在线观看免费1级| 国产丝袜一区二区三区免费视频| 日本午夜精品理论片a级appf发布| 国产精品网站入口| 成年人精品视频| 亚洲国产精品va在线看黑人| 欧美中文在线视频| 欧美精品九九久久| 日韩欧美在线视频免费观看| 精品亚洲永久免费精品|