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

KVC原理與數據篩選

開發 前端
基本的訪問器方法、變量的查找和異常處理已經清楚的知道了。那么上面的例子是如何出現的呢?明明傳入的是字符串,最后賦值的時候轉變為訪問器方法所對應的類型?繼續刨根問底!

1、前言

在技術論壇中看到一則很有意思的KVC案例:

@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
Person *person = [Person new];
person.name = @"Tom";
person.age = 10;
[person setValue:@"100" forKey:@"age"];//此處賦值為字符串,類中屬性為Integer

第一反應是崩潰,因為OC是類型敏感的。可是自己實現并打印后的結果出于意料,沒有崩潰且賦值成功。所以有了深入了解KVC的內部實現的想法!

2、什么是KVC

key-value-coding:鍵值編碼,一種可以通過鍵名間接訪問和賦值對象屬性的機制
KVC是通過NSObject、NSArray、NSDictionary等的類別來實現的
主要方法包括一下幾個:

- (nullable id)valueForKey:(NSString *)key;
- (void)setValue:(nullable id)value forKey:(NSString *)key;
- (void)setNilValueForKey:(NSString *)key;
- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;
- (nullable id)valueForUndefinedKey:(NSString *)key;

3、KVC執行分析

那么上面的案例中的- (void)setValue:(nullable id)value forKey:(NSString *)key;是怎樣的執行過程呢?借助反匯編工具獲得Foundation.framework部分源碼(為了解決和系統API沖突問題增加前綴_d,NS替換為DS),以此分析KVC執行過程。(流程中的邊界判斷等已經忽略,如想了解可以參考源碼,本文只探究主流程。)

3.1 設置屬性

3.1.1 查找訪問器方法或成員變量

+ (DSKeyValueSetter *)_d_createValueSetterWithContainerClassID:(id)containerClassID key:(NSString *)key {
DSKeyValueSetter *setter = nil;
char key_cstr_upfirst[key_cstr_len + 1];
key_cstr[key_cstr_len + 1];
...
Method method = NULL;
//按順序尋找set<Key>,_set<Key>,setIs<Key>。找到后則生成對應的seter
if ((method = DSKeyValueMethodForPattern(self, "set%s:", key_cstr_upfirst)) ||
(method = DSKeyValueMethodForPattern(self, "_set%s:", key_cstr_upfirst)) ||
(method = DSKeyValueMethodForPattern(self, "setIs%s:", key_cstr_upfirst))
) { //生成Method:包含selector,IMP。返回和參數類型字符串
setter = [[DSKeyValueMethodSetter alloc] initWithContainerClassID:containerClassID key:key method:method];
} else if ([self accessInstanceVariablesDirectly]) {//如果沒有找到對應的訪問器方且工廠方法accessInstanceVariablesDirectly == ture ,則按照順序查找查找成員變量_<key>,_is<Key>,<key>,is<Key>(注意key的首字母大小寫,查找到則生成對應的setter)
Ivar ivar = NULL;
if ((ivar = DSKeyValueIvarForPattern(self, "_%s", key_cstr)) ||
(ivar = DSKeyValueIvarForPattern(self, "_is%s", key_cstr_upfirst)) ||
(ivar = DSKeyValueIvarForPattern(self, "%s", key_cstr)) ||
(ivar = DSKeyValueIvarForPattern(self, "is%s", key_cstr_upfirst))
) {
setter = [[DSKeyValueIvarSetter alloc] initWithContainerClassID:containerClassID key:key containerIsa:self ivar:ivar];
}
}
...
return setter;
}

查找順序如下:

  1. 查找訪問器方法:set,_set,setIs
  2. 如果步驟1中沒找到對應的方法且 accessInstanceVariablesDirectly == YES

則查找順序如下:_,_is,,is
查找不到則調用valueForUndefinedKey并拋出異常

3.1.2 生成setter

+ (DSKeyValueSetter *)_d_createOtherValueSetterWithContainerClassID:(id)containerClassID key:(NSString *)key {
return [[DSKeyValueUndefinedSetter alloc] initWithContainerClassID:containerClassID key:key containerIsa:self];
}
//構造方法確定方法編號 d_setValue:forUndefinedKey: 和方法指針IMP _DSSetValueAndNotifyForUndefinedKey
- (id)initWithContainerClassID:(id)containerClassID key:(NSString *)key containerIsa:(Class)containerIsa {
...
return [super initWithContainerClassID:containerClassID key:key implementation:method_getImplementation(class_getInstanceMethod(containerIsa, @selector(d_setValue:forUndefinedKey:))) selector:@selector(d_setValue:forUndefinedKey:) extraArguments:arguments count:1];
}

3.1.3 賦值

基本的訪問器方法、變量的查找和異常處理已經清楚的知道了。那么上面的例子是如何出現的呢?明明傳入的是字符串,最后賦值的時候轉變為訪問器方法所對應的類型?繼續刨根問底!

DSKeyValueSetter對象已經生成,即確定了發送消息的對象object、訪問器方法名SEL、訪問器函數指針IMP、以及使用KVC時傳入的Key和Value。下面進入方法調用階段:_DSSetUsingKeyValueSetter(self,setter, value);

IMP指針為_DSSetIntValueForKeyWithMethod其定義如下:之所以有文章開頭提到的效果就是這里起了作用,在IMP調用的時候做了[value valueGetSelectorName],將對應的NSNumber轉換為簡單數據類型。這里是intValue。

void _DSSetIntValueForKeyWithMethod(id object, SEL selector,id value, NSString *key, Method method) {// object:person selector:setAge:  value:@(100)  key:age  method:selector + IMP + 返回類型和參數類型 即_extraArgument2,其在第一步查找到訪問器方法后生成
__DSSetPrimitiveValueForKeyWithMethod(object, selector, value, key, method, int, intValue);
}
#define
if (value) {\
void (*imp)(id,SEL,valueType) = (void (*)(id,SEL,valueType))method_getImplementation(method);\
imp(object, method_getName(method), [value valueGetSelectorName]);\調用person的setAge:方法。參數為100
}\
else {\
[object setNilValueForKey:key];\
}\
}while(0)
//如果第一步中沒有找到訪問器方法只找到了成員變量則直接執行賦值操作
void _DSSetIntValueForKeyInIvar(id object, SEL selector, id value, NSString *key, Ivar ivar) {
if (value) {
*(int *)object_getIvarAddress(object, ivar) = [value intValue];
}
else {
[object setNilValueForKey:key];
}
}

起始問題完美解決!執行流程如下:

3.2 取值

3.2.1 查找訪問器方法或成員變量

+ (DSKeyValueGetter *)_d_createValueGetterWithContainerClassID:(id)containerClassID key:(NSString *)key {
DSKeyValueGetter * getter = nil;
...
Method getMethod = NULL;
if((getMethod = DSKeyValueMethodForPattern(self,"get%s",keyCStrUpFirst)) ||
(getMethod = DSKeyValueMethodForPattern(self,"%s",keyCStr)) ||
(getMethod = DSKeyValueMethodForPattern(self,"is%s",keyCStrUpFirst)) ||
(getMethod = DSKeyValueMethodForPattern(self,"_get%s",keyCStrUpFirst)) ||
(getMethod = DSKeyValueMethodForPattern(self,"_%s",keyCStr))) {
getter = [[DSKeyValueMethodGetter alloc] initWithContainerClassID:containerClassID key:key method:getMethod];
}// 查找對應的訪問器方法
...
else if([self accessInstanceVariablesDirectly]) {//查找屬性
Ivar ivar = NULL;
if((ivar = DSKeyValueIvarForPattern(self, "_%s", keyCStr)) ||
(ivar = DSKeyValueIvarForPattern(self, "_is%s", keyCStrUpFirst)) ||
(ivar = DSKeyValueIvarForPattern(self, "%s", keyCStr)) ||
(ivar = DSKeyValueIvarForPattern(self, "is%s", keyCStrUpFirst))
) {
getter = [[DSKeyValueIvarGetter alloc] initWithContainerClassID:containerClassID key:key containerIsa:self ivar:ivar];
}
}
}
if(!getter) {
getter = [self _d_createValuePrimitiveGetterWithContainerClassID:containerClassID key:key];
}
return getter;
}

  1. 按照get,,is,_的順序查找成員方法
  2. 如果1.沒有找到對應的方法且accessInstanceVariablesDirectly==YES,則繼續查找成員變量,查找順序為_,_is,,is
  3. 如果1,2沒有找到對應的方法和屬性則調用 valueForUndefinedKey:并拋出異常

3.2.2 如上步驟沒定位到訪問器方法或成員變量則走下面的流程生成對應的getter

訪問器方法生成IMP
- (id)initWithContainerClassID:(id)containerClassID key:(NSString *)key method:(Method)method {
NSUInteger methodArgumentsCount = method_getNumberOfArguments(method);
NSUInteger extraAtgumentCount = 1;
if(methodArgumentsCount == 2) {
char *returnType = method_copyReturnType(method);
IMP imp = NULL;
switch (returnType[0]) {
...
case 'i': {
imp = (IMP)_DSGetIntValueWithMethod;
} break;
...
free(returnType);
if(imp) {
void *arguments[3] = {0};
if(extraAtgumentCount > 0) {
arguments[0] = method;
}
return [super initWithContainerClassID:containerClassID key:key implementation:imp selector:method_getName(method) extraArguments:arguments count:extraAtgumentCount];
}
}

單步調試后可以看到具體的IMP類型

定義如下:

NSNumber * _DSGetIntValueWithMethod(id object, SEL selctor, Method method) {// 
return [[[NSNumber alloc] initWithInt: ((int (*)(id,SEL))method_getImplementation(method))(object, method_getName(method))] autorelease];
}

3.2.3 取值

取值調用如下:

4、簡單數據類型KVC包裝和拆裝關系

NSNunber:

NSValue

5、KVC高級

修改數組中對象的屬性[array valueForKeyPath:@”uppercaseString”]利用KVC可以批量修改屬性的成員變量值

求和,平均數,最大值,最小值NSNumbersum= [array valueForKeyPath:@”@sum.self”];NSNumberavg= [array valueForKeyPath:@”@avg.self”];NSNumbermax= [array valueForKeyPath:@”@max.self”];NSNumbermin= [array valueForKeyPath:@”@min.self”];

6、數據篩選

經過上面的分析可以明白KVC的真正執行流程。下面結合日常工程中的實際應用來優雅的處理數據篩選問題。使用KVC處理可以減少大量for的使用并增加代碼可讀性和健壯性。
如圖所示:

項目中的細節如下:修改拒收數量時更新總妥投數和總拒收數、勾選明細更新總妥投數和總拒收數、全選、清空、反選。如果用通常的做法是每次操作都要循環去計算總數和記錄選擇狀態。下面是采用KVC的實現過程。
模型涉及:

@property (nonatomic,copy)NSString* skuCode;
@property (nonatomic,copy)NSString* goodsName;
@property (nonatomic,assign)NSInteger totalAmount;
@property (nonatomic,assign)NSInteger rejectAmount;
@property (nonatomic,assign)NSInteger deliveryAmount;
///單選用
@property (nonatomic, assign) BOOL selected;

1)更新總數

- (void)updateDeliveryInfo {
//總數
NSNumber *allDeliveryAmount = [self.orderDetailModel.deliveryGoodsDetailList valueForKeyPath:@"@sum.totalAmount"];
//妥投數
NSNumber *allRealDeliveryAmount = [self.orderDetailModel.deliveryGoodsDetailList valueForKeyPath:@"@sum.deliveryAmount"];
//拒收數
NSNumber *allRejectAmount = [self.orderDetailModel.deliveryGoodsDetailList valueForKeyPath:@"@sum.rejectAmount"];
}

2)全選
[self.orderDetailModel.deliveryGoodsDetailList setValue:@(YES) forKeyPath:@”selected”];

3)清空
[self.orderDetailModel.deliveryGoodsDetailList setValue:@(NO) forKeyPath:@”selected”];

4)反選

NSPredicate *selectedPredicate = [NSPredicate predicateWithFormat:@"selected == %@",@(YES)];
NSArray *selectedArray = [self.orderDetailModel.deliveryGoodsDetailList filteredArrayUsingPredicate:selectedPredicate];
NSPredicate *unSelectedPredicate = [NSPredicate predicateWithFormat:@"selected == %@",@(NO)];
NSArray *unSelectedArray = [self.orderDetailModel.deliveryGoodsDetailList filteredArrayUsingPredicate:unSelectedPredicate];
[selectedArray setValue:@(NO) forKeyPath:@"selected"];
[unSelectedArray setValue:@(YES) forKeyPath:@"selected"];

7、總結

KVC在處理簡單數據類型時會經過數據封裝和拆裝并轉換為對應的數據類型。通過KVC的特性我們可以在日常使用中更加優雅的對數據進行篩選和處理。優點如下:可閱讀性更高,健壯性更好。

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2025-03-03 10:28:38

2020-06-17 12:36:45

查詢數據Python

2023-07-31 08:39:19

MongoDB查詢語法

2023-05-08 00:08:51

Hive機制場景

2011-07-25 17:07:16

iPhone KVO KVC

2013-10-24 09:40:31

CommVault數據保護歸檔

2022-06-30 10:00:28

數據系統

2023-11-13 23:06:52

Android序列化

2017-02-09 17:00:00

iOSSwiftKVC

2023-06-08 07:25:56

數據庫索引數據結構

2011-04-21 10:06:40

SQL篩選

2021-05-06 08:55:24

ThreadLocal多線程多線程并發安全

2020-03-05 09:33:15

數據庫事務隔離事務

2022-06-13 16:09:17

PandasPython

2025-02-26 07:59:47

2014-12-18 13:20:09

Docker容器鏡像數據卷

2013-09-22 14:02:09

內存數據庫

2021-12-20 00:03:38

Webpack運行機制

2023-02-07 09:17:19

Java注解原理

2010-09-13 10:26:48

點贊
收藏

51CTO技術棧公眾號

国产一区白浆| 99a精品视频在线观看| 国产精品欧美综合在线| 国产精品自拍视频| 青青草手机在线观看| 欧美成人午夜77777| 欧美色图一区二区三区| 大伊香蕉精品视频在线| 成年人在线看| 成人小视频免费在线观看| 国产精品久久二区| 久久国产在线视频| 色综合狠狠操| 日韩激情视频在线| 久草福利在线观看| 日韩制服诱惑| 五月天丁香久久| 国产高潮呻吟久久久| 青青草免费在线| 国产精品资源网| 国产精品久久久久久av| 欧美一级高潮片| 国产精品99久久| 亚洲欧美在线第一页| 第一页在线视频| 日韩一级特黄| 欧美性极品xxxx娇小| 欧美 日韩 国产精品| 在线观看免费黄色| 国产精品一区二区黑丝| 欧美猛男性生活免费| 国产一二三av| 国产成人影院| 亚洲精品国产欧美| 中文字幕一区二区三区人妻在线视频 | 免费欧美激情| 亚洲精品国精品久久99热一| 曰本三级日本三级日本三级| 国产高清精品二区| 欧美日本一区二区三区四区| 丁香婷婷激情网| 亚洲风情在线资源| 污片在线观看一区二区| www.日本少妇| 成人高潮aa毛片免费| 亚洲激情综合网| 国产高潮呻吟久久久| 麻豆tv免费在线观看| 国产精品进线69影院| 亚洲欧洲一区二区在线观看| 飘雪影院手机免费高清版在线观看 | 黄色影院在线播放| 久久久噜噜噜久噜久久综合| 蜜桃av久久久亚洲精品| 三级毛片在线免费看| 96av麻豆蜜桃一区二区| 精品麻豆av| 每日更新av在线播放| 久久青草欧美一区二区三区| 欧美极品一区| yiren22亚洲综合伊人22| 欧美激情综合在线| 亚洲午夜精品久久久中文影院av | 久久久久久久久久久免费 | 日韩欧美在线第一页| 97在线播放视频| 欧美与亚洲与日本直播| 欧美日韩在线观看一区二区 | 亚洲欧美日韩一区| 久久久久久久久影视| 青草影视电视剧免费播放在线观看| 亚洲码国产岛国毛片在线| 成人国产在线看| 国产高清中文字幕在线| 日本高清不卡一区| 日本黄色福利视频| 91蝌蚪精品视频| 日韩风俗一区 二区| 成都免费高清电影| 日韩毛片视频| 欧美精品videos性欧美| 美女又爽又黄免费视频| 免费精品视频最新在线| 99国产在线视频| 欧美新色视频| 国产精品久久久久久久久图文区 | 一区二区三区视频在线观看| 伊人久久av导航| 在线午夜影院| 亚洲成人精品在线观看| 国产91对白刺激露脸在线观看| 欧美韩国亚洲| 欧美一区二区三区日韩| 99久久免费看精品国产一区| 欧美一二区在线观看| 另类天堂视频在线观看| 亚洲黄色激情视频| 美日韩一级片在线观看| 懂色一区二区三区av片| 浮生影视网在线观看免费| 亚洲视频一区在线| 青青在线视频观看| 麻豆精品国产| 亚洲最新av在线网站| 麻豆影视在线播放| 久久蜜桃精品| 成人毛片网站| 欧美在线一二三区| 韩国中文字幕在线| 岛国av一区二区| 久久久精品高清| 啪啪国产精品| 粗暴蹂躏中文一区二区三区| 天堂网视频在线| 国产成人啪午夜精品网站男同| 欧美日韩国产高清视频| 在线中文字幕-区二区三区四区| 日韩欧美国产免费播放| 免费观看一区二区三区| 日韩欧美一区二区三区在线视频| 久久久久久久久中文字幕| 在线免费a视频| 久久婷婷综合激情| avav在线播放| 电影一区中文字幕| 一个色综合导航| 色婷婷av国产精品| 成人亚洲一区二区一| 成年人黄色在线观看| 在线成人视屏| 亚洲欧洲一区二区三区久久| 国产精品suv一区二区69| 国产米奇在线777精品观看| 日本一区二区在线| 日韩精品美女| 亚洲国产91精品在线观看| 欧美色图一区二区| 国产精品亚洲一区二区三区妖精| 亚洲国产综合自拍| 日韩制服一区| 亚洲区一区二区| 亚洲精品中文字幕乱码三区91| 成人丝袜18视频在线观看| 国产美女视频免费| 国产精品久久久久久久久久辛辛 | 91欧美日韩一区| aaa在线观看| 欧美日韩国产综合草草| 国产探花视频在线播放| 日韩精品乱码av一区二区| 欧美日韩一区在线观看视频| 国产伦精品一区二区三区视频金莲| 亚洲第一中文字幕| 国产欧美日韩另类| 91蜜桃在线免费视频| 日本成年人网址| 禁断一区二区三区在线| 国产精品欧美风情| 日本三级视频在线观看| 91精品欧美久久久久久动漫 | 亚洲日韩视频| 久久综合九色欧美狠狠| 欧美二三四区| 中文字幕av日韩| 国产理论视频在线观看| 一区二区三区四区在线| 久久久久成人精品无码中文字幕| 国产亚洲午夜| 亚洲v欧美v另类v综合v日韩v| 日韩第二十一页| 欧美日韩福利在线观看| 五月天婷婷激情网| 欧美在线免费观看亚洲| frxxee中国xxx麻豆hd| 大桥未久av一区二区三区中文| 少妇无码av无码专区在线观看| 亚洲va久久| 成人黄色片在线| 岛国片av在线| 亚洲图片欧美午夜| 国产999久久久| 欧美日韩亚洲一区二区| 登山的目的在线| 99久久久国产精品免费蜜臀| 狠狠热免费视频| 午夜精品剧场| 日本在线视频一区| 日韩一区二区三区色| 欧洲成人在线观看| 国产高清一区二区三区视频 | 亚洲图片88| 精品欧美一区二区在线观看| 亚洲第一在线播放| 日韩美女视频一区二区 | 色综合久久天天综线观看| 天堂成人在线| 欧美放荡的少妇| 日本韩国欧美中文字幕| 亚洲视频一区二区在线| 在线免费看黄视频| 国产98色在线|日韩| 免费黄色一级网站| 亚洲区第一页| 香蕉精品视频在线| 亚洲区小说区| 国产精品精品软件视频| 欧美美女福利视频| 欧美中文字幕精品| 新版中文在线官网| 日韩在线观看免费网站 | eeuss鲁片一区二区三区| 国产精品高清在线观看| 狠狠操一区二区三区| 精品国产一区久久久| 日本在线视频1区| 精品免费一区二区三区| 一级全黄裸体免费视频| 日本韩国欧美一区| 日本va欧美va国产激情| 亚洲激情网站免费观看| 国精品人伦一区二区三区蜜桃| 337p粉嫩大胆色噜噜噜噜亚洲| 韩国一区二区三区四区| 极品少妇xxxx精品少妇| 999精彩视频| 丝袜脚交一区二区| 国产中文字幕免费观看| 精品91在线| 国产一区二区四区| 91精品99| 在线天堂一区av电影| 欧美日韩激情| 欧美日韩中文国产一区发布| 老牛国内精品亚洲成av人片| 国产99在线播放| 三级欧美日韩| 成人免费观看网站| jizz国产精品| 国产一区二区不卡视频在线观看| 日韩精品一级| eeuss一区二区三区| 日韩精品视频在线看| 成人av免费在线看| 少妇精品在线| 成人自拍网站| 欧美一性一交| 你懂的视频在线一区二区| 羞羞色国产精品网站| 欧美高清性xxxxhd| 国产一区网站| 亚洲欧洲中文| 91精品久久久久久久蜜月| 中文字幕久精品免| 中文字幕午夜精品一区二区三区| 国产91porn| 在线欧美福利| 久久网站免费视频| 日本va欧美va精品发布| xxww在线观看| 国内久久精品视频| 韩国三级视频在线观看| 91原创在线视频| www.黄色在线| 亚洲私人影院在线观看| 九九热这里有精品视频| 精品久久久精品| 国产偷人爽久久久久久老妇app | 欧美成人日韩| 你真棒插曲来救救我在线观看| 国产视频一区三区| 爱情岛论坛vip永久入口| 精品一区二区三区免费| 丰满少妇xbxb毛片日本| 久久久久99精品国产片| 欧美黄色免费网站| 男人天堂久久久| 欧美人交a欧美精品| 成人国产电影在线观看| 国产成人精品在线播放| 国产精品色婷婷在线观看| 狠狠色狠狠色综合人人| 成人精品中文字幕| 成人在线视频一区二区三区| 免费视频久久| 亚洲自拍第三页| 91在线视频免费91| 成人日韩视频| y111111国产精品久久婷婷| 秋霞蜜臀av久久电影网免费| 亚洲国产精品久久久久久女王| 91成人精品| 日本www高清视频| 激情综合网天天干| 亚洲一级中文字幕| 亚洲美女在线一区| 亚洲精品中文字幕乱码三区91| 91精品国产手机| 男女网站在线观看| 欧美国产日产韩国视频| 123成人网| 久久国产精品高清| 午夜国产精品视频| 欧美在线aaa| www国产精品av| 久久久久久国产精品免费播放| 色94色欧美sute亚洲线路一久| 亚洲成人av综合| 视频一区视频二区国产精品| 在线毛片观看| 国产精华一区| 亚洲综合专区| www.久久久精品| 国产色爱av资源综合区| 国产女同在线观看| 欧美一区二区三区成人| 国产乱视频在线观看| 91高清免费视频| 亚洲一二av| 黄黄视频在线观看| 毛片av中文字幕一区二区| 大又大又粗又硬又爽少妇毛片| 亚洲午夜精品在线| 超碰在线观看99| 久久亚洲私人国产精品va| 免费视频观看成人| 日韩在线国产| 丝袜美腿成人在线| 亚洲理论片在线观看| 狠狠色狠狠色综合日日五| 婷婷开心激情网| 久久久视频在线| 凹凸成人在线| 男人天堂手机在线视频| 国产成人啪免费观看软件| 破处女黄色一级片| 欧美一区二区三区在线观看视频| 1024免费在线视频| 国产欧美欧洲在线观看| 色喇叭免费久久综合网| 国内国产精品天干天干| 一区二区中文字幕在线| 一级爱爱免费视频| 北条麻妃一区二区三区中文字幕| 欧美美女福利视频| 久久99九九| 懂色av色香蕉一区二区蜜桃| 神马影院一区二区| 日韩av午夜在线观看| jizz中文字幕| 在线观看日韩电影| 粉嫩av在线播放| 国产精品亚洲一区二区三区| 日韩精品欧美激情一区二区| 黄色手机在线视频| 国产精品国产三级国产普通话三级 | 亚洲午夜一二三区视频| 可以免费观看的毛片| 亚州成人av在线| 亚洲人成网77777色在线播放| 国产日韩一区二区在线| 国产欧美日产一区| 国产永久免费视频| 欧美黄色小视频| 四虎5151久久欧美毛片| 91av俱乐部| 亚洲欧美偷拍另类a∨色屁股| 亚洲精品中文字幕成人片| 97超级碰在线看视频免费在线看| 亚洲成a人片77777在线播放| 天天爽人人爽夜夜爽| 亚洲欧美视频在线观看视频| 人妻妺妺窝人体色www聚色窝| 欧美综合在线观看| 99久久激情| 国产精品久久不卡| 欧美日韩五月天| 黄网av在线| 日本中文不卡| 豆国产96在线|亚洲| chinese国产精品| 欧美成人激情视频| 香蕉精品久久| 免费国偷自产拍精品视频| 福利视频导航一区| 国产原创精品视频| 国内精品久久国产| 久久精品久久久精品美女| 国产无遮挡又黄又爽在线观看| 亚洲无av在线中文字幕| 91成人短视频| 污网站免费在线| 福利一区视频在线观看| 成人在线影视| 日本免费高清不卡| 粉嫩一区二区三区性色av| 最好看的日本字幕mv视频大全| 欧美激情一区二区三级高清视频| 精品国产一区二区三区| 精品一区二区三区四区五区六区| 欧美三级视频在线|