在Swift中采用Cocoa設計模式,怎么操作允耿?

使用 Cocoa 現(xiàn)有的一些設計模式借笙,是幫助開發(fā)者開發(fā)一款擁有合理設計思路、穩(wěn)定的性能右犹、良好的可擴展性應用的有效方法之一提澎。這些模式都依賴于在 Objective-C 中定義的類。因為 Swift 與 Objective-C 的互用性念链,所以你依然可以在 Swift 代碼中使用這些設計模式盼忌。在一些情況下,你甚至可以使用 Swift 語言的特性擴展或簡化這些 Cocoa 設計模式掂墓,使這些設計模式更強大谦纱、更易于使用。


委托(Delegation)

在 Swift 和 Objective-C 中君编,委托通常由一個定義交互方法和遵循規(guī)范的委托屬性的協(xié)議表示跨嘉。與 Objective-C 相比,當你在 Swift 中繼承一個委托時吃嘿,雖然繼承模式不變祠乃,但是內(nèi)部的實現(xiàn)已經(jīng)改變了梦重。就像在 Objective-C 中,在你向委托發(fā)送消息之前亮瓷,不管它是不是 nil 你都會去查看琴拧,如果定義的方法是非必須實現(xiàn)的方法,不管委托有沒有實現(xiàn)這個方法嘱支,你也都會去查看蚓胸。而在 Swift 中,通過保持類型安全的特性除师,可以有效的消除這些繁瑣沛膳、不必要的行為問題。

下面列出的代碼可以說明這個過程:

  1. 檢查 myDelegate 不為 nil汛聚。
  2. 檢查 myDelegate 是否實現(xiàn)了繼承的 window:willUseFullScreenContentSize: 方法锹安。
  3. 如果myDelegate 不為 nil 并且實現(xiàn)了 window:willUseFullScreenContentSize: 方法,那么調(diào)用該方法倚舀,將該方法的返回值分配給名為 fullScreenSize 的屬性八毯。
  4. 將該方法的返回值輸出在控制臺。

作為一個開發(fā)者瞄桨,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS開發(fā)交流群:130595548讶踪,不管你是小白還是大牛都歡迎入駐 芯侥,讓我們一起進步,共同發(fā)展H榧ァ(群內(nèi)會免費提供一些群主收藏的免費學習書籍資料以及整理好的幾百道面試題和答案文檔V椤)

1.  // @inteface MyObject : NSObject
2.  // @property (nonatomic, weak) id<NSWindowDelegate> delegate;
3.  // @end
4.  if let fullScreenSize = myDelegate?.window?(myWindow, willUseFullScreenContentSize: mySize) {
5.  println(NSStringFromSize(fullScreenSize))
6.  }

注意: 在一個完全使用 Swift 編寫的 app 中,在定義 delegate 屬性時云石,它作為一個不定值的 NSWindowDelegate 對象唉工,并將初始值設為 nil。

延遲初始化(Lazy Initialization)

你可以在 Lazy Stored Properties 中了解到更多關于延遲初始化的信息汹忠。

錯誤報告(Error Reporting)

Swift 中的錯誤報告模式沿用了 Objective-C 的模式淋硝,但 Swift 中不定值返回值的新特性給我們帶來了額外的好處。舉個很簡單的例子宽菜,你用 Bool 值作為一個函數(shù)的返回值谣膳,用于標識該函數(shù)是否執(zhí)行成功,當你需要輸出錯誤信息時铅乡,你可以在函數(shù)中添加一個NSErrorPointer 類型的輸出參數(shù) NSError继谚。這個類型類似 Objective-C 中的 NSError **,并增加了內(nèi)存安全性和非強制性的傳參阵幸。你可以使用 & 運算符作為前綴引用一個不定值 NSError 類型作為 NSErrorPointer 對象傳遞錯誤信息花履。如下面的代碼所示:

1.  var writeError : NSError?
2.  let written = myString.writeToFile(path, atomically: false,
3.  encoding: NSUTF8StringEncoding,
4.  error: &writeError)
5.  if !written {
6.  if let error = writeError {
7.  println("write failure: \(error.localizedDescription)")
8.  }
9.  }

當你實現(xiàn)自己的方法時芽世,你需要配置一個 NSErrorPointer 對象,并將 NSErrorPointer 對象的 memory 屬性設為你創(chuàng)建的NSError 對象诡壁。首先檢查調(diào)用者傳遞的參數(shù)济瓢,確保它是一個非 nil 的 NSError 對象。

1.  func contentsForType(typeName: String! error: NSErrorPointer) -> AnyObject! {
2.  if cannotProduceContentsForType(typeName) {
3.  if error {
4.  error.memory = NSError(domain: domain, code: code, userInfo: [:])
5.  }
6.  return nil
7.  }
8.  // ...
9.  }

Target-Action模式(Target-Action)

當有特定事件發(fā)生欢峰,需要一個對象向另一個對象發(fā)送消息時葬荷,我們通常采用 Cocoa 的 Target-Action 設計模式。Swift 和 Objective-C 中的 Target-Action 模型基本類似纽帖。在 Swift 中宠漩,你可以使用 Selector 類型達到 Objective-C 中 selectors 的效果。請在Objective-C Selectors 中查看在 Swift 中使用 Target-Action 設計模式的示例懊直。

類型匹配與統(tǒng)一規(guī)范(Introspection)

在 Objective-C 中扒吁,你可以使用 isKindOfClass: 方法檢查某個對象是否是指定類型,可以使用 conformsToProtocol: 方法檢查某個對象是否遵循特定協(xié)議的規(guī)范室囊。在 Swift 中雕崩,你可以使用 is 運算符完成上述的功能,或者也可以使用 as? 向下匹配指定類型融撞。

你可以使用 is 運算符檢查一個實例是否是指定的子類盼铁。如果該實例是指定的子類,那么 is 運算結果為 true尝偎,反之為false饶火。

1.  if object is UIButton {
2.  // object is of type UIButton
3.  } else {
4.  // object is not of type UIButton
5.  }

你也可以使用 as? 運算符嘗試向下匹配子類型,as? 運算符返回不定值致扯,結合 if-let 語句使用肤寝。

1.  if let button = object as? UIButton {
2.  // object is successfully cast to type UIButton and bound to button
3.  } else {
4.  // object could not be cast to type UIButton
5.  }

請在 Type Casting 中查看更多信息。

檢查匹配協(xié)議的語法與檢查匹配類的語法是一樣的抖僵,下面是使用 as? 檢查匹配協(xié)議的示例:

1.  if let dataSource = object as? UITableViewDataSource {
2.  // object conforms to UITableViewDataSource and is bound to dataSource
3.  } else {
4.  // object not conform to UITableViewDataSource
5.  }

注意鲤看,當做完匹配之后,dataSource 會轉換為 UITableViewDataSource 類型耍群,所以你只能訪問和調(diào)用UITableViewDataSource 協(xié)議定義的屬性和方法义桂。當你想進行其他操作時,必須將其轉換為其他的類型蹈垢。

可以在 Protocols 查看更多相關信息澡刹。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市耘婚,隨后出現(xiàn)的幾起案子罢浇,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嚷闭,死亡現(xiàn)場離奇詭異攒岛,居然都是意外死亡,警方通過查閱死者的電腦和手機胞锰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門灾锯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嗅榕,你說我怎么就攤上這事顺饮。” “怎么了凌那?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵兼雄,是天一觀的道長。 經(jīng)常有香客問我帽蝶,道長赦肋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任励稳,我火速辦了婚禮佃乘,結果婚禮上,老公的妹妹穿的比我還像新娘驹尼。我一直安慰自己趣避,他們只是感情好,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布新翎。 她就那樣靜靜地躺著鹅巍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪料祠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天澎羞,我揣著相機與錄音髓绽,去河邊找鬼。 笑死妆绞,一個胖子當著我的面吹牛顺呕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播括饶,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼株茶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了图焰?” 一聲冷哼從身側響起启盛,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后僵闯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卧抗,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年鳖粟,在試婚紗的時候發(fā)現(xiàn)自己被綠了社裆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡向图,死狀恐怖泳秀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情榄攀,我是刑警寧澤嗜傅,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站航攒,受9級特大地震影響磺陡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜漠畜,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一币他、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧憔狞,春花似錦蝴悉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至簇抵,卻和暖如春庆杜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背碟摆。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工晃财, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人典蜕。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓断盛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親愉舔。 傳聞我的和親對象是個殘疾皇子钢猛,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容