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

面向協議編程與 Cocoa 的邂逅 (上)

網絡 網絡管理
本文 (上) 主要介紹了一些理論方面的內容,包括面向對象編程存在的問題,面向協議的基本概念和決策模型等,下半部分主要展示了一些筆者日常使用面向協議思想和 Cocoa 開發結合的示例代碼,并對其進行了一些解說。

[[403413]]

本文轉載自微信公眾號「Swift 社區」,作者Onevcat。轉載本文請聯系Swift 社區公眾號。

本文筆者在 MDCC 16 (移動開發者大會) 上 iOS 專場中的主題演講的文字整理。發布于 2016年11月29日 最后更新于 2020年10月22日

您可以在這里[1]找到演講使用的 Keynote,部分示例代碼可以在 MDCC 2016 的 官方 repo[2]中找到。因為全部內容比較長,所以分成了上下兩個部分,本文 (上) 主要介紹了一些理論方面的內容,包括面向對象編程存在的問題,面向協議的基本概念和決策模型等,下半部分主要展示了一些筆者日常使用面向協議思想和 Cocoa 開發結合的示例代碼,并對其進行了一些解說。

1. 引子

面向協議編程 (Protocol Oriented Programming,以下簡稱 POP) 是 Apple 在 2015 年 WWDC 上提出的 Swift 的一種編程范式。相比與傳統的面向對象編程 (OOP),POP 顯得更加靈活。結合 Swift 的值語義特性和 Swift 標準庫的實現,這一年來大家發現了很多 POP 的應用場景。

本次演講希望能在介紹 POP 思想的基礎上,引入一些日常開發中可以使用 POP 的場景,讓與會來賓能夠開始在日常工作中嘗試 POP,并改善代碼設計。

2. 什么是 Swift 協議

2.1 Protocol

Swift 標準庫中有 50 多個復雜不一的協議,幾乎所有的實際類型都是滿足若干協議的。protocol 是 Swift 語言的底座,語言的其他部分正是在這個底座上組織和建立起來的。這和我們熟知的面向對象的構建方式很不一樣。

一個最簡單但是有實際用處的 Swift 協議定義如下:

  1. protocol Greetable { 
  2.     var name: String { get } 
  3.     func greet() 

這幾行代碼定義了一個名為 Greetable 的協議,其中有一個 name 屬性的定義,以及一個 greet 方法的定義。

所謂協議,就是一組屬性和/或方法的定義,而如果某個具體類型想要遵守一個協議,那它需要實現這個協議所定義的所有這些內容。協議實際上做的事情不過是“關于實現的約定”。

2.2 面向對象

在深入 Swift 協議的概念之前,我想先重新讓大家回顧一下面向對象。相信我們不論在教科書或者是博客等各種地方對這個名詞都十分熟悉了。那么有一個很有意思,但是其實并不是每個程序員都想過的問題,面向對象的核心思想究竟是什么?

我們先來看一段面向對象的代碼:

  1. class Animal { 
  2.     var leg: Int { return 2 } 
  3.     func eat() { 
  4.         print("eat food."
  5.     } 
  6.     func run() { 
  7.         print("run with \(leg) legs"
  8.     } 
  9.  
  10. class Tiger: Animal { 
  11.     override var leg: Int { return 4 } 
  12.     override func eat() { 
  13.         print("eat meat."
  14.     } 
  15.  
  16. let tiger = Tiger() 
  17. tiger.eat() // "eat meat" 
  18. tiger.run() // "run with 4 legs" 

父類 Animal 定義了動物的 leg (這里應該使用虛類,但是 Swift 中沒有這個概念,所以先請無視這里的 return 2),以及動物的 eat 和 run 方法,并為它們提供了實現。子類的 Tiger 根據自身情況重寫了 leg (4 條腿)和 eat (吃肉),而對于 run,父類的實現已經滿足需求,因此不必重寫。

我們看到 Tiger 和 Animal 共享了一部分代碼,這部分代碼被封裝到了父類中,而除了 Tiger 的其他的子類也能夠使用 Animal 的這些代碼。這其實就是 OOP 的核心思想 - 使用封裝和繼承,將一系列相關的內容放到一起。

我們的前輩們為了能夠對真實世界的對象進行建模,發展出了面向對象編程的概念,但是這套理念有一些缺陷。雖然我們努力用這套抽象和繼承的方法進行建模,但是實際的事物往往是一系列特質的組合,而不單單是以一脈相承并逐漸擴展的方式構建的。

所以最近大家越來越發現面向對象很多時候其實不能很好地對事物進行抽象,我們可能需要尋找另一種更好的方式。

2.3 面向對象編程的困境

2.3.1 橫切關注點

我們再來看一個例子。這次讓我們遠離動物世界,回到 Cocoa,假設我們有一個 ViewController,它繼承自 UIViewController,我們向其中添加一個 myMethod:

  1. class ViewCotroller: UIViewController 
  2.     // 繼承 
  3.     // view, isFirstResponder()... 
  4.      
  5.     // 新加 
  6.     func myMethod() { 
  7.          
  8.     } 

如果這時候我們又有一個繼承自 UITableViewController 的 AnotherViewController,我們也想向其中添加同樣的 myMethod:

  1. class AnotherViewController: UITableViewController 
  2.     // 繼承 
  3.     // tableView, isFirstResponder()... 
  4.      
  5.     // 新加 
  6.     func myMethod() { 
  7.          
  8.     } 

這時,我們迎來了 OOP 的第一個大困境,那就是我們很難在不同繼承關系的類里共用代碼。這里的問題用“行話”來說叫做“橫切關注點” (Cross-Cutting Concerns)。我們的關注點 myMethod 位于兩條繼承鏈 (UIViewController -> ViewCotroller 和 UIViewController -> UITableViewController -> AnotherViewController) 的橫切面上。

面向對象是一種不錯的抽象方式,但是肯定不是最好的方式。它無法描述兩個不同事物具有某個相同特性這一點。在這里,特性的組合要比繼承更貼切事物的本質。

想要解決這個問題,我們有幾個方案:

  • Copy & Paste

這是一個比較糟糕的解決方案,但是演講現場還是有不少朋友選擇了這個方案,特別是在工期很緊,無暇優化的情況下。這誠然可以理解,但是這也是壞代碼的開頭。我們應該盡量避免這種做法。

  • 引入 BaseViewController

在一個繼承自 UIViewController 的 BaseViewController 上添加需要共享的代碼,或者干脆在 UIViewController 上添加 extension。看起來這是一個稍微靠譜的做法,但是如果不斷這么做,會讓所謂的 Base 很快變成垃圾堆。職責不明確,任何東西都能扔進 Base,你完全不知道哪些類走了 Base,而這個“超級類”對代碼的影響也會不可預估。

  • 依賴注入

通過外界傳入一個帶有 myMethod 的對象,用新的類型來提供這個功能。這是一個稍好的方式,但是引入額外的依賴關系,可能也是我們不太愿意看到的。

  • 多繼承

當然,Swift 是不支持多繼承的。不過如果有多繼承的話,我們確實可以從多個父類進行繼承,并將 myMethod 添加到合適的地方。有一些語言選擇了支持多繼承 (比如 C++),但是它會帶來 OOP 中另一個著名的問題:菱形缺陷。

2.3.2 菱形缺陷

上面的例子中,如果我們有多繼承,那么 ViewController 和 AnotherViewController 的關系可能會是這樣的:

此處有圖片

在上面這種拓撲結構中,我們只需要在 ViewController 中實現 myMethod,在 AnotherViewController 中也就可以繼承并使用它了。看起來很完美,我們避免了重復。

但是多繼承有一個無法回避的問題,就是兩個父類都實現了同樣的方法時,子類該怎么辦?我們很難確定應該繼承哪一個父類的方法。因為多繼承的拓撲結構是一個菱形,所以這個問題又被叫做菱形缺陷 (Diamond Problem)。

像是 C++ 這樣的語言選擇粗暴地將菱形缺陷的問題交給程序員處理,這無疑非常復雜,并且增加了人為錯誤的可能性。而絕大多數現代語言對多繼承這個特性選擇避而遠之。

2.3.3 動態派發安全性

Objective-C 恰如其名,是一門典型的 OOP 語言,同時它繼承了 Small Talk 的消息發送機制。這套機制十分靈活,是 OC 的基礎思想,但是有時候相對危險。考慮下面的代碼:

  1. ViewController *v1 = ... 
  2. [v1 myMethod]; 
  3.  
  4. AnotherViewController *v2 = ... 
  5. [v2 myMethod]; 
  6.  
  7. NSArray *array = @[v1, v2]; 
  8. for (id obj in array) { 
  9.     [obj myMethod]; 

我們如果在 ViewController 和 AnotherViewController 中都實現了 myMethod 的話,這段代碼是沒有問題的。myMethod 將會被動態發送給 array 中的 v1 和 v2。但是,要是我們有一個沒有實現 myMethod 的類型,會如何呢?

  1. NSObject *v3 = [NSObject new] 
  2. // v3 沒有實現 `myMethod` 
  3.  
  4. NSArray *array = @[v1, v2, v3]; 
  5. for (id obj in array) { 
  6.     [obj myMethod]; 
  7.  
  8. // Runtime error: 
  9. // unrecognized selector sent to instance blabla 

編譯依然可以通過,但是顯然,程序將在運行時崩潰。Objective-C 是不安全的,編譯器默認你知道某個方法確實有實現,這是消息發送的靈活性所必須付出的代價。

而在 app 開發看來,用可能的崩潰來換取靈活性,顯然這個代價太大了。雖然這不是 OOP 范式的問題,但它確實在 Objective-C 時代給我們帶來了切膚之痛。

2.3.4 三大困境

我們可以總結一下 OOP 面臨的這幾個問題:

  • 動態派發安全性
  • 橫切關注點
  • 菱形缺陷

首先,在 OC 中動態派發讓我們承擔了在運行時才發現錯誤的風險,這很有可能是發生在上線產品中的錯誤。其次,橫切關注點讓我們難以對對象進行完美的建模,代碼的重用也會更加糟糕。

3. 協議擴展和面向協議編程

3.1 使用協議解決 OOP 困境

協議并不是什么新東西,也不是 Swift 的發明。在 Java 和 C# 里,它叫做 Interface。而 Swift 中的 protocol 將這個概念繼承了下來,并發揚光大。讓我們回到一開始定義的那個簡單協議,并嘗試著實現這個協議:

  1. protocol Greetable { 
  2.     var name: String { get } 
  3.     func greet() 
  1. struct Person: Greetable { 
  2.     let name: String 
  3.     func greet() { 
  4.         print("你好 \(name)"
  5.     } 
  6. Person(name"Wei Wang").greet() 

實現很簡單,Person 結構體通過實現 name 和 greet 來滿足 Greetable。在調用時,我們就可以使用 Greetable 中定義的方法了。

3.1.1 動態派發安全性

除了 Person,其他類型也可以實現 Greetable,比如 Cat:

  1. struct Cat: Greetable { 
  2.     let name: String 
  3.     func greet() { 
  4.         print("meow~ \(name)"
  5.     } 

現在,我們就可以將協議作為標準類型,來對方法調用進行動態派發了:

  1. let array: [Greetable] = [ 
  2.   Person(name"Wei Wang"),  
  3.   Cat(name"onevcat")] 
  4. for obj in array { 
  5.  obj.greet() 
  6. // 你好 Wei Wang 
  7. // meow~ onevcat 

對于沒有實現 Greetbale 的類型,編譯器將返回錯誤,因此不存在消息誤發送的情況:

  1. struct Bug: Greetable { 
  2.     let name: String 
  3.  
  4. // Compiler Error:  
  5. // 'Bug' does not conform to protocol 'Greetable' 
  6. // protocol requires function 'greet()' 

這樣一來,動態派發安全性的問題迎刃而解。如果你保持在 Swift 的世界里,那這個你的所有代碼都是安全的。

  • 動態派發安全性
  • 橫切關注點
  • 菱形缺陷

3.1.2 橫切關注點

使用協議和協議擴展,我們可以很好地共享代碼。回到上一節的 myMethod 方法,我們來看看如何使用協議來搞定它。首先,我們可以定義一個含有 myMethod 的協議:

  1. protocol P { 
  2.     func myMethod() 

注意這個協議沒有提供任何的實現。我們依然需要在實際類型遵守這個協議的時候為它提供具體的實現:

  1. // class ViewController: UIViewController 
  2. extension ViewController: P { 
  3.     func myMethod() { 
  4.         doWork() 
  5.     } 
  6.  
  7. // class AnotherViewController: UITableViewController 
  8. extension AnotherViewController: P { 
  9.     func myMethod() { 
  10.         doWork() 
  11.     } 

你可能不禁要問,這和 Copy & Paste 的解決方式有何不同?沒錯,答案就是 – 沒有不同。不過稍安勿躁,我們還有其他科技可以解決這個問題,那就是協議擴展。協議本身并不是很強大,只是靜態類型語言的編譯器保證,在很多靜態語言中也有類似的概念。

那到底是什么讓 Swift 成為了一門協議優先的語言?真正使協議發生質變,并讓大家如此關注的原因,其實是在 WWDC 2015 和 Swift 2 發布時,Apple 為協議引入了一個新特性,協議擴展,它為 Swift 語言帶來了一次革命性的變化。

所謂協議擴展,就是我們可以為一個協議提供默認的實現。對于 P,可以在 extension P 中為 myMethod 添加一個實現:

  1. protocol P { 
  2.     func myMethod() 
  3.  
  4. extension P { 
  5.     func myMethod() { 
  6.         doWork() 
  7.     } 

有了這個協議擴展后,我們只需要簡單地聲明 ViewController 和 AnotherViewController 遵守 P,就可以直接使用 myMethod 的實現了:

  1. extension ViewController: P { } 
  2. extension AnotherViewController: P { } 
  3.  
  4. viewController.myMethod() 
  5. anotherViewController.myMethod() 

不僅如此,除了已經定義過的方法,我們甚至可以在擴展中添加協議里沒有定義過的方法。在這些額外的方法中,我們可以依賴協議定義過的方法進行操作。我們之后會看到更多的例子。總結下來:

  • 協議定義
    • 提供實現的入口
    • 遵循協議的類型需要對其進行實現
  • 協議擴展
    • 為入口提供默認實現
    • 根據入口提供額外實現

這樣一來,橫切點關注的問題也簡單安全地得到了解決。

  • 動態派發安全性
  • 橫切關注點
  • 菱形缺陷

3.1.3 菱形缺陷

最后我們看看多繼承。多繼承中存在的一個重要問題是菱形缺陷,也就是子類無法確定使用哪個父類的方法。在協議的對應方面,這個問題雖然依然存在,但卻是可以唯一安全地確定的。我們來看一個多個協議中出現同名元素的例子:

  1. protocol Nameable { 
  2.     var name: String { get } 
  3.  
  4. protocol Identifiable { 
  5.     var name: String { get } 
  6.     var id: Int { get } 

如果有一個類型,需要同時實現兩個協議的話,它必須提供一個 name 屬性,來同時滿足兩個協議的要求:

  1. struct Person: Nameable, Identifiable { 
  2.     let name: String  
  3.     let id: Int 
  4.  
  5. // `name` 屬性同時滿足 Nameable 和 Identifiable 的 name 

這里比較有意思,又有點讓人困惑的是,如果我們為其中的某個協議進行了擴展,在其中提供了默認的 name 實現,會如何。考慮下面的代碼:

  1. extension Nameable { 
  2.     var name: String { return "default name" } 
  3.  
  4. struct Person: Nameable, Identifiable { 
  5.     // let name: String  
  6.     let id: Int 
  7.  
  8. // Identifiable 也將使用 Nameable extension 中的 name 

這樣的編譯是可以通過的,雖然 Person 中沒有定義 name,但是通過 Nameable 的 name (因為它是靜態派發的),Person 依然可以遵守 Identifiable。不過,當 Nameable 和 Identifiable 都有 name的協議擴展的話,就無法編譯了:

  1. extension Nameable { 
  2.     var name: String { return "default name" } 
  3.  
  4. extension Identifiable { 
  5.     var name: String { return "another default name" } 
  6.  
  7. struct Person: Nameable, Identifiable { 
  8.     // let name: String  
  9.     let id: Int 
  10.  
  11. // 無法編譯,name 屬性沖突 

這種情況下,Person 無法確定要使用哪個協議擴展中 name 的定義。在同時實現兩個含有同名元素的協議,并且它們都提供了默認擴展時,我們需要在具體的類型中明確地提供實現。這里我們將 Person 中的 name 進行實現就可以了:

  1. extension Nameable { 
  2.     var name: String { return "default name" } 
  3.  
  4. extension Identifiable { 
  5.     var name: String { return "another default name" } 
  6.  
  7. struct Person: Nameable, Identifiable { 
  8.     let name: String  
  9.     let id: Int 
  10.  
  11. Person(name"onevcat", id: 123).name // onevcat 

這里的行為看起來和菱形問題很像,但是有一些本質不同。首先,這個問題出現的前提條件是同名元素以及同時提供了實現,而協議擴展對于協議本身來說并不是必須的。

其次,我們在具體類型中提供的實現一定是安全和確定的。當然,菱形缺陷沒有被完全解決,Swift 還不能很好地處理多個協議的沖突,這是 Swift 現在的不足。

  • 動態派發安全性
  •  橫切關注點
  • 菱形缺陷

作者:王巍(onevcat),江湖人稱 "喵神",他是 ObjC 中國組織的發起人和領導者,也是著名開源框架 Kingfisher 的作者。

 

責任編輯:武曉燕 來源: Swift 社區
相關推薦

2021-06-04 09:01:27

Cocoa 協議編程 Swift

2016-12-12 15:22:41

編程

2022-07-30 23:41:53

面向過程面向對象面向協議編程

2011-08-11 15:46:55

CocoaCocoa Touch框架

2011-07-08 18:03:30

Cocoa Touch 網絡

2011-05-11 15:27:58

Windows OOPCocoa MVCCocoa

2018-07-23 15:55:28

協議自定義viewSwift

2011-07-22 15:50:06

Cocoa MVC 視圖

2009-04-22 09:20:26

Erlang并發函數式

2015-10-16 09:59:52

SwiftCocoa

2011-08-15 15:56:29

Cocoa編程模塊

2013-07-30 09:42:41

實現編程接口編程對象編程

2015-03-20 09:54:44

網絡編程面向連接無連接

2010-07-09 11:12:09

UDP協議

2024-01-03 13:38:00

C++面向對象編程OOP

2014-05-08 14:13:00

Java面向GC

2009-06-16 15:02:18

面向對象編程PHP異常PHP代理

2011-09-07 15:33:33

CocoaiOSObjective-C

2011-07-28 18:11:18

Objective-C Cocoa 編程

2011-08-15 16:28:06

Cocoa內存管理
點贊
收藏

51CTO技術棧公眾號

亚洲人视频在线观看| 欧美成人精品欧美一级私黄| 日韩精选视频| 国产精品久久久久久久久动漫 | 日韩高清一区| 婷婷国产在线综合| 色一情一乱一伦一区二区三区| 91好色先生tv| 一本久久知道综合久久| 日韩网站在线观看| 精品人妻在线视频| 性欧美videohd高精| ...av二区三区久久精品| 国产一区二区高清不卡| 亚洲一区 中文字幕| 在线日本高清免费不卡| 最近2019年日本中文免费字幕| 国产一级免费片| 日韩成人在线一区| 一本色道久久综合亚洲aⅴ蜜桃| 黄色网址在线免费看| 亚洲欧洲精品视频| 国产乱码精品一区二区三区五月婷| 欧美一级视频在线观看| 日韩精品123区| 国产欧美高清视频在线| 日韩欧美激情一区| 午夜精品中文字幕| 欧美动物xxx| 五月天网站亚洲| 国产91沈先生在线播放| 日本福利在线| 久久无码av三级| 国产精品v欧美精品v日韩| 亚洲在线观看av| 视频精品一区二区| 欧美与欧洲交xxxx免费观看| 久久网中文字幕| 国产高清欧美| 日韩在线视频线视频免费网站| 91精品国产自产| 国产香蕉精品| 欧美sm极限捆绑bd| 成年人网站av| 在线免费成人| 6080日韩午夜伦伦午夜伦| 天美星空大象mv在线观看视频| 成人动漫一区| 欧美午夜精品久久久久久久| 国产精品又粗又长| 92久久精品| 一区二区三区日韩精品| 青青草视频在线视频| 色www永久免费视频首页在线| 亚洲人成精品久久久久久| 综合操久久久| jizz性欧美| 亚洲免费观看高清完整版在线观看熊| 中文字幕日韩精品久久| 老司机午夜在线| 国产精品国产三级国产普通话蜜臀 | 久久九九国产视频| 玛雅亚洲电影| 欧美在线啊v一区| 日韩av在线中文| 日韩成人在线电影| 欧美一级免费大片| 俄罗斯黄色录像| 免费萌白酱国产一区二区三区| 日韩av在线免费观看| 人妻丰满熟妇av无码久久洗澡 | 国内精品福利视频| 久久久久网站| 国产日本欧美视频| 国产永久免费视频| 国产91精品入口| 精品一区二区三区视频日产| 你懂的免费在线观看| 中文字幕av一区二区三区免费看 | 欧美日韩一区二区三区在线观看免| 日韩一区av| 国产精品无遮挡| www.国产在线视频| 日韩欧美看国产| 911国产精品| 一起草在线视频| 国内精品久久久久久99蜜桃| 久久久99久久精品女同性| 久久国产精品波多野结衣av| 亚洲一区二区三区免费在线观看 | 99re只有精品| gogo大胆日本视频一区| 日韩伦理一区二区三区av在线| 日本不卡不卡| 精品国产999| 青青草原国产在线视频| 精品按摩偷拍| 日韩在线小视频| 国产a∨精品一区二区三区仙踪林| 日韩精品电影在线| 国产乱码精品一区二区三区不卡| 国产乱视频在线观看| 有码一区二区三区| 99草草国产熟女视频在线| 免费观看亚洲视频大全| 亚洲图片在线综合| 久久免费视频精品| 久久精品国产一区二区| 久久一区二区三区av| www在线免费观看视频| 欧美性20hd另类| 深夜做爰性大片蜜桃| 精品日产免费二区日产免费二区| 欧美成人午夜免费视在线看片| 久久夜色精品国产噜噜亚洲av| 国产精品白丝jk白祙喷水网站| 你懂的视频在线一区二区| jizz性欧美| 精品视频色一区| 国产吞精囗交久久久| 欧美日韩亚洲国产精品| 国产精品视频大全| 亚洲精品国产精| 综合久久综合久久| 欧美大尺度做爰床戏| 香蕉久久精品日日躁夜夜躁| 欧美高清在线观看| 国产日韩免费视频| 国产精品免费人成网站| 欧洲av无码放荡人妇网站| 国产精东传媒成人av电影| 久久精品夜夜夜夜夜久久| 一级一片免费看| 久久蜜臀中文字幕| 久久久久久久久久久视频| jazzjazz国产精品久久| 久久精品视频在线播放| 91久久国语露脸精品国产高跟| 国产日韩欧美在线一区| 欧美视频在线播放一区| 精品国产乱子伦一区二区| 超薄丝袜一区二区| 国产美女裸体无遮挡免费视频| 国产精品视频一二三| 九色porny91| 精品国产一区二区三区四区| 国产不卡av在线免费观看| 色吊丝在线永久观看最新版本| 亚洲va韩国va欧美va| 性高潮久久久久久| 国产精品久久| 国产偷国产偷亚洲高清97cao| 青青在线视频| 亚洲第一区中文99精品| 日本熟妇毛耸耸xxxxxx| av网站免费线看精品| 国产深夜男女无套内射| 日韩有码一区| 国产精品久久久久久久久久久久久| 久久手机免费观看| 欧美性一二三区| 啪啪一区二区三区| 国产精品 欧美精品| 99久久99久久精品| 欧美一区自拍| 国产成人avxxxxx在线看| av在线免费一区| 欧美一区二区三区精品| 国产在线视频在线观看| 26uuu成人网一区二区三区| 不要播放器的av网站| 成人精品天堂一区二区三区| 91系列在线播放| 欧美韩日亚洲| 亚洲欧美在线免费| 在线观看免费高清视频| 亚洲最大成人综合| 特级西西人体4444xxxx| 日韩综合一区二区| 国产高潮呻吟久久久| caoporn成人免费视频在线| 国产a∨精品一区二区三区不卡| 最新av网站在线观看| 日韩欧美在线网站| 日韩欧美成人一区二区三区| 中文字幕精品一区二区精品绿巨人 | 国产精品一品二品| 欧洲黄色一级视频| 91欧美在线| 国产免费一区| 成人免费视频观看| 午夜欧美不卡精品aaaaa| 国产对白叫床清晰在线播放| 日韩免费一区二区| 久久精品五月天| 夜夜嗨av一区二区三区中文字幕 | 自拍偷拍欧美专区| 鲁丝一区鲁丝二区鲁丝三区| av在线亚洲一区| 浅井舞香一区二区| 综合图区亚洲| 亚洲天堂av在线播放| 欧美77777| 欧美日韩综合色| 久久夜色精品亚洲| 亚洲人成在线观看一区二区| 星空大象在线观看免费播放| 性xxxx18| 亚洲精选在线| 四虎永久免费网站| 国产欧美久久一区二区三区| 成人免费在线看片| 亚州欧美在线| 国产成一区二区| 日韩精品av| 久久久久在线观看| 国产精品久久麻豆| 中文字幕成人在线| 久久精品国产亚洲a∨麻豆| 精品日韩一区二区| a在线观看视频| 欧美日韩免费高清一区色橹橹| 美日韩一二三区| 亚洲国产精品自拍| 青娱乐免费在线视频| 国产精品国模大尺度视频| a资源在线观看| 99精品视频在线观看免费| 欧美性猛交xx| 精久久久久久久久久久| 一道本在线免费视频| 日韩综合小视频| 草草草在线视频| 久久免费高清| 精品免费国产一区二区| 亚洲中午字幕| 国产视频九色蝌蚪| 国产视频久久| 久久综合色视频| 一道本一区二区| 5月婷婷6月丁香| 99视频精品| 97国产在线播放| 国产日韩一区二区三区在线| 亚洲熟妇国产熟妇肥婆| 国产欧美日韩亚洲一区二区三区| 亚洲丝袜自拍清纯另类| 男女私大尺度视频| 欧美午夜一区| 3d动漫一区二区三区| 国产精品美女久久久浪潮软件| 日韩国产欧美亚洲| 视频一区二区欧美| 五月花丁香婷婷| 激情五月播播久久久精品| 午夜一级免费视频| 国产老妇另类xxxxx| 少妇精品无码一区二区| 成人免费观看av| 国产在线观看无码免费视频| 久久久久久夜精品精品免费| 久久中文字幕精品| 亚洲同性同志一二三专区| 欧美色图一区二区| 午夜久久久久久久久| 在线观看日本视频| 精品1区2区3区| 国产欧美综合视频| 亚洲成人黄色在线观看| 日本亚洲欧美| 色偷偷综合社区| 精精国产xxxx视频在线中文版| 51精品国产黑色丝袜高跟鞋| 欧美日韩不卡| 亚洲综合在线小说| 欧美综合精品| 亚洲一区综合| 精品成人一区| www.天天射.com| 国产精品一二二区| www.免费av| 中文字幕一区在线观看| 久久精品视频9| 欧美在线视频日韩| 精品人妻一区二区三区四区不卡| 日韩国产激情在线| 麻豆影视国产在线观看| 性欧美视频videos6一9| 免费日韩成人| 精品亚洲第一| 国产韩国精品一区二区三区| 日日摸日日碰夜夜爽无码| 欧美bbbbb| 无码国产69精品久久久久网站| 国产拍揄自揄精品视频麻豆| 欧美日韩免费做爰视频| 日本乱码高清不卡字幕| 亚洲精品无码专区| 在线日韩精品视频| 国产色播av在线| 成人av番号网| 精品久久久久中文字幕小说 | 亚洲精品小说| 免费裸体美女网站| 成人丝袜视频网| 国产探花视频在线| 欧美视频免费在线观看| jizz中国女人| 中文字幕在线视频日韩| 一本大道色婷婷在线| 大波视频国产精品久久| 日韩毛片视频| 97公开免费视频| 成人动漫一区二区| 免费麻豆国产一区二区三区四区| 在线观看国产精品网站| 欧美18xxxxx| 韩国福利视频一区| 亚洲国产视频二区| 在线免费观看成人网| 日本亚洲视频在线| 亚洲熟妇一区二区三区| 午夜精品视频一区| 亚洲第一色网站| 欧美精品在线网站| 日韩一级视频| 亚洲欧美日韩精品综合在线观看| 亚洲在线网站| 久久久久久久久久久国产精品| 亚洲一卡二卡三卡四卡五卡| 国产精品欧美亚洲| 精品国产一区久久久| 精品久久福利| 一区不卡字幕| 美女在线观看视频一区二区| 蜜臀久久99精品久久久久久| 欧美视频在线看| 青春草在线观看| 日本午夜人人精品| 曰本一区二区三区视频| 97国产精东麻豆人妻电影| 91在线免费视频观看| 日本中文字幕网| 亚洲激情在线观看| 亚洲性色av| 欧美极品一区| 玖玖国产精品视频| 精品日韩在线视频| 欧美日韩日日骚| 久久日韩视频| 444亚洲人体| 黄色日韩在线| 日本黄色免费观看| 色综合久久88色综合天天 | 欧美成人黄色小视频| 日韩在线观看一区二区三区| 久草视频这里只有精品| 不卡的看片网站| 黄色片视频免费| 最近2019年日本中文免费字幕| 99久久99九九99九九九| 欧美日韩午夜爽爽| a美女胸又www黄视频久久| 天堂中文字幕在线观看| 在线看日韩欧美| 经典三级久久| 欧美日韩精品在线一区二区| 国产亚洲一区字幕| 国产一区二区在线视频聊天| 欧美激情综合亚洲一二区 | 成人永久免费视频| 国产精品500部| 在线观看视频亚洲| 欧美一区在线观看视频| 浮妇高潮喷白浆视频| 国产精品全国免费观看高清| 国产伦一区二区| 91av中文字幕| 91亚洲人成网污www| 国产亚洲精品成人a| 色欧美日韩亚洲| 性xxxfreexxxx性欧美| 久久亚洲午夜电影| 韩国成人在线视频| 久久久久久久久影院| 最新69国产成人精品视频免费| 午夜免费欧美电影| 乱子伦视频在线看| 亚洲激情六月丁香| 粉嫩一区二区三区国产精品| 99九九视频| 奇米精品一区二区三区四区| 免费无码毛片一区二区app| 亚洲日本中文字幕免费在线不卡| 久久久91麻豆精品国产一区| 久久国产色av免费观看| 亚洲午夜电影网| 午夜激情视频在线| 久久综合福利| 国产suv精品一区二区三区|