最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Swift中閉包實(shí)戰(zhàn)案例詳解

 更新時(shí)間:2017年03月07日 10:44:34   作者:張?jiān)讫? 
接觸過Swift的小伙伴對(duì)“閉包”應(yīng)該不陌生,相當(dāng)于OC中的Block,是Swift語法中比較難理解的一塊。下面這篇文章主要介紹了關(guān)于Swift中閉包實(shí)戰(zhàn)的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。

前言

無論蘋果的官方文檔還是由官方文檔衍生出來的一些文章和書籍都比較重視基礎(chǔ)語法知識(shí)的講解,對(duì)于實(shí)戰(zhàn)中的應(yīng)用提及的都很少,所以當(dāng)我們想使用“閉包”解決一些問題的時(shí)候,會(huì)忽然出現(xiàn)看著一堆理論知識(shí)卻不知從何下手的尷尬感,這就是理論和時(shí)實(shí)戰(zhàn)的區(qū)別了。

本文不贅述Swift閉包的的基本語法了,百度或者Google下有很多資料。如題所示本文著重講述Swift閉包的一些實(shí)戰(zhàn)案例,有需要的小伙伴可以參考下,經(jīng)驗(yàn)豐富的大神也請(qǐng)指教。

關(guān)于如何理解閉包

學(xué)習(xí)閉包的第一個(gè)難點(diǎn)就是理解閉包,可能很多人用了很久的閉包都還不太清楚閉包到底是什么,我這里提供一種理解思路,僅供參考。

對(duì)于很多iOS開發(fā)者來說一開始接觸到Swift閉包會(huì)試圖用OC中的Block去理解,當(dāng)然這會(huì)對(duì)我們的理解有一定幫助,就好比很多人學(xué)習(xí)英語:tomato->西紅柿->🍅,而不是tomato-> 🍅,而一個(gè)嬰兒剛開始接觸語言時(shí)候就是直接由tomato的發(fā)音聯(lián)想到🍅,而后再去學(xué)習(xí)🍅的單詞拼寫,這是人類與生俱來的學(xué)習(xí)語言的邏輯流程,所以我們不妨按照這種思維邏輯去學(xué)習(xí)和理解Swift的閉包。

1、閉包是什么

這就好比一個(gè)嬰兒好奇西紅柿是什么,家長會(huì)將一個(gè)真實(shí)的西紅柿拿到他的面前,看一看,摸一摸,聞一聞,嘗一嘗。對(duì)于Swift的閉包,我們首先不需要知道是它在語法上如何定義的,而是要知道閉包的本質(zhì)。

閉包的本質(zhì)是代碼塊,它是函數(shù)的升級(jí)版本,函數(shù)是有名稱、可復(fù)用的代碼塊,閉包則是比函數(shù)更加靈活的匿名代碼塊。

2、為什么需要閉包

當(dāng)一個(gè)嬰兒知道了西紅柿是什么,自然而然就會(huì)想到西紅柿有什么用,那么我們自然也會(huì)問閉包在Swift中有何用處呢?

函數(shù)已經(jīng)可以滿足我們開發(fā)中大部分的需求了,那么為什么還需要閉包呢。在開發(fā)中我們經(jīng)常需要傳遞各種數(shù)據(jù),我們習(xí)慣了傳遞一個(gè)值:Int,一串符號(hào):String,一個(gè)對(duì)象:Class,但是有時(shí)我們需要傳遞一種處理問題的邏輯,我們常用的類型似乎滿足不了這種需求,而函數(shù)恰好是一種處理問題的邏輯,為了讓函數(shù)像Int、Float、String等常用類型一樣靈活的傳遞和調(diào)用,閉包就出現(xiàn)了。

綜上所述,我們可以知道閉包本質(zhì)上和函數(shù)一樣都是代碼塊,而閉包更加靈活。

閉包、嵌套函數(shù)、函數(shù)

更好地使用閉包前需要理清3者的聯(lián)系和區(qū)別

首先看3種函數(shù)的定義:

//函數(shù)
func eatTomatos(a: Int, b: Int) -> Int {
 return a + b
}

//嵌套函數(shù)
func eatTomatos(a: Int, b: Int) -> Int {
 //嵌套函數(shù)
 func digest(a: Int, b: Int) -> Int {
  return 2 * a + b
 }

 return digest(a: a, b: b)
}

//閉包
var eatTomatos = {(a: Int, b: Int) -> Int in
 return a + b
}

從上面的定義可以看出函數(shù)和嵌套函數(shù)其實(shí)是一回事,唯一的區(qū)別是,嵌套函數(shù)是定義在一個(gè)函數(shù)內(nèi)部的函數(shù),對(duì)外部是隱藏的,只能在其定義的函數(shù)內(nèi)部有效。而閉包與函數(shù)的不同要多一些:1、不需要使用func關(guān)鍵字,2、其次函數(shù)有名稱如:eatTomatos,而閉包是沒有名稱的,3、閉包的參數(shù)和函數(shù)體都要使用{ }包起來,在參數(shù)后要使用in關(guān)鍵字連接函數(shù)體,4、閉包可以作為一種類型賦值給一個(gè)變量,上面代碼中的閉包類型是: (Int, Int) -> Int

上面從定義上分析了3者的不同,下面從功能上區(qū)分下。

1、函數(shù)是全局的,不能捕獲上下文中的變量;而嵌套函數(shù)和閉包可以直接嵌套在上下文中使用的,因此可以捕獲上下文中的變量,需要注意的是每一個(gè)閉包都只會(huì)持有一個(gè)它所捕獲的變量的副本,如下:

override func viewDidLoad() {
  super.viewDidLoad()
  print(eatTomatos(a: 1, b: 2))//③
  print(eatTomatos(a: 2, b: 3))//④
}

func eatTomatos(a: Int, b: Int) -> Int {
 var numArray: Array<Int> = Array.init()

 //嵌套函數(shù)
 func digest(a: Int, b: Int) -> Int {
  numArray.append(a)
  numArray.append(b)
  print(numArray.count)//②
  return 2 * a + b
 }

 print(numArray.count)//①

 return digest(a: a, b: b)
}

//打印的結(jié)果依次(①②③④)是:
0
2
4
0
2
7

2、閉包可以作為參數(shù)或者返回值,如下:

// 作為參數(shù)
override func viewDidLoad() {
 super.viewDidLoad()
 cookTomates { (a, b) in
  print(a)
  print(b)
 }
}

func cookTomates(tomato: (Int, Int) -> Void){
 tomato(1, 2)
}

cookTomates函數(shù)將閉包(Int, Int) -> Void作為參數(shù),并且可以在函數(shù)內(nèi)部操作這個(gè)閉包

在調(diào)用cookTomates函數(shù)式需要將給這個(gè)閉包參數(shù)賦值,并且閉包中的參數(shù)名需要調(diào)用的時(shí)候自行命名。

//作為返回值
override func viewDidLoad() {
 super.viewDidLoad()

 let tomato = gainTomatos()
 print(tomato(2, 3))

}
var eatTomatos: (Int, Int) -> Int = {(a: Int, b: Int) -> Int in
 return a + b
}
func gainTomatos() -> (Int, Int) -> Int {
 return eatTomatos
}

函數(shù)gainTomatos將閉包(Int, Int) -> Int作為返回值,這里返回的是(Int, Int) -> Int的一個(gè)實(shí)例,調(diào)用者便可以利用返回的實(shí)例獲取(Int, Int) -> Int閉包處理參數(shù)的邏輯,實(shí)現(xiàn)代碼的傳遞和復(fù)用

為你的閉包類型起別名

閉包類型不像其他常用類型看起來比較簡潔,有參數(shù)、返回值、關(guān)鍵字、符號(hào)構(gòu)成,影響閱讀和糾錯(cuò),因此為常用的閉包類型起一個(gè)別名很有必要。

如下,為(Int, Int) -> Int閉包類型起別名

typealias Tomato = (Int, Int) -> Int

因此上面閉包當(dāng)做返回值使用的代碼便可以改寫如下:

override func viewDidLoad() {
 super.viewDidLoad()

 let tomato = gainTomatos()
 print(tomato(2, 3))

}

var eatTomatos: Tomato = {(a: Int, b: Int) -> Int in
 return a + b
}

func gainTomatos() -> Tomato {
 return eatTomatos
}

當(dāng)我們把(Int, Int) -> Int類型抽象為Tomato后,不僅僅是代碼看起來更加簡潔,也更接近我們使用的其他參數(shù)類型,更加便于理解

閉包傳值

OC中常用的傳值方法有代理、Block、通知等,對(duì)應(yīng)到Swift Block就由閉包替代。

如下需要使用閉包將B中的a、b值傳遞到A中

override func viewDidLoad() {
 super.viewDidLoad()

 let a: A = A()
 a.fromB()

}

typealias Tomato = (Int, Int) -> Int

class A: NSObject {
 let b: B = B()

 func fromB() {
  b.tomato = {
   (x, y) -> Int in
   return x + y
  }
  print(b.toA())
 }

}

class B: NSObject {
 var tomato: Tomato?

 func toA() -> Int {
  let a = 3
  let b = 4
  return tomato!(a, b)
 }

}

由上可以總結(jié)出閉包傳值的流程:

1️、首先為自己的閉包類型起一個(gè)別名,便于使用;

2️、在需要把值傳遞給另外一個(gè)對(duì)象的類里聲明一個(gè)閉包類型的變量,對(duì)應(yīng)到上面的代碼中就是B;

3️、在需要接收值的類里為閉包類型賦值,從而在此閉包內(nèi)便可以獲取傳遞的值。

注意:

這里著重描述傳值的流程,在開發(fā)的時(shí)候還需判斷閉包是否為nil,否則會(huì)導(dǎo)致崩潰;

閉包作為參數(shù)傳值

在使用AFN或者SDWebImage的時(shí)候,通過Block獲取請(qǐng)求的數(shù)據(jù)很方便,那么在Swift中如何使用閉包實(shí)現(xiàn)這種效果呢。

其實(shí)上面在說閉包作為參數(shù)使用的時(shí)候,已經(jīng)實(shí)現(xiàn)了這種傳值的方式,這里舉另外一個(gè)例子,我們?cè)谑褂玫谌綆斓臅r(shí)候通常會(huì)將其再封裝一次,避免由于第三方庫不維護(hù)或者出現(xiàn)較大更新的時(shí)候增加不必要的工作量,這里以簡單封裝Alamofire為例,代碼如下:

import UIKit
import Alamofire
import SwiftyJSON

class ZYLResponse: NSObject {
 //接收數(shù)據(jù)是否成功
 var isSuccess: Bool = false
 //接收到的字典數(shù)據(jù)
 var dict: Dictionary<String, Any>?
 //接收到的數(shù)組數(shù)據(jù)
 var array: Array<Any>?
 //錯(cuò)誤信息
 var error: Error?
 //JSON
 var json:JSON?

}

typealias DataReply = (ZYLResponse) -> Void

class ZYLNetTool: NSObject {

 ///POST請(qǐng)求
 open static func post(url: String, parameters: Dictionary<String, Any>?, complete: @escaping DataReply) {
  Alamofire.request(url, method: .post, parameters: parameters).responseJSON { (response) in
   let myResponse = ZYLResponse()
   myResponse.isSuccess = response.result.isSuccess
   myResponse.dict = response.result.value as! Dictionary<String, Any>?
   myResponse.array = response.result.value as? Array<Any>
   myResponse.error = response.result.error
   myResponse.json = JSON(data: response.data!)

   complete(myResponse)
  }
 }

 ///GET請(qǐng)求
 open static func get(url: String, parameters: Dictionary<String, Any>?, complete: @escaping DataReply) {
  Alamofire.request(url, method: .get, parameters: parameters).responseJSON { (response) in
   let myResponse = ZYLResponse()
   myResponse.isSuccess = response.result.isSuccess
   myResponse.dict = response.result.value as! Dictionary<String, Any>?
   myResponse.array = response.result.value as? Array<Any>
   myResponse.error = response.result.error
   myResponse.json = JSON(data: response.data!)

   complete(myResponse)
  }
 }

}

//調(diào)用
  ZYLNetTool.post(url: HTTP_ACTIVATE_PORT, parameters: paraDict, complete: { (response) in
   if response.isSuccess {
    //請(qǐng)求數(shù)據(jù)成功

   } else {
    //請(qǐng)求數(shù)據(jù)失敗

   }
  })

注意:

1、使用閉包時(shí)要注意管理內(nèi)存;

2、當(dāng)作閉包為函數(shù)參數(shù)使用時(shí)可以脫離函數(shù)獨(dú)立使用時(shí),要將此閉包聲明為逃逸閉包,在參數(shù)類型前面加上@escaping,否則會(huì)報(bào)錯(cuò)。

總結(jié)

接觸一種新的事物之前總會(huì)覺得很難,當(dāng)我們學(xué)會(huì)后發(fā)現(xiàn)其實(shí)很簡單,難的不是這個(gè)新事物本身,而是我們的大腦出于習(xí)慣很難接受新的事物,總是需要一定的過程。記得學(xué)C語言時(shí)很難理解指針,學(xué)C++時(shí)很難理解面向?qū)ο?,學(xué)OC時(shí)很難理解Block,而Swift作為一種新的語言,必然會(huì)有很多新的事物讓我們難以理解,比如閉包、元組、可選類型、函數(shù)式編程等等,以上就是這篇文章的全部內(nèi)容了,本文只對(duì)閉包發(fā)表一點(diǎn)拙見,如果有什么不足的地方還望指正,謝謝。

相關(guān)文章

  • swift計(jì)步器CMPedometer的使用方法

    swift計(jì)步器CMPedometer的使用方法

    這篇文章主要為大家詳細(xì)介紹了swift計(jì)步器CMPedometer的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • swift在IOS應(yīng)用圖標(biāo)上添加提醒個(gè)數(shù)的方法

    swift在IOS應(yīng)用圖標(biāo)上添加提醒個(gè)數(shù)的方法

    本文是通過swift語言實(shí)現(xiàn)在應(yīng)用圖標(biāo)右上角添加消息個(gè)數(shù)提醒的功能,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看下吧
    2016-08-08
  • Swift實(shí)現(xiàn)3D輪播圖效果

    Swift實(shí)現(xiàn)3D輪播圖效果

    這篇文章主要為大家詳細(xì)介紹了Swift實(shí)現(xiàn)3D輪播圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • Swift自定義iOS中的TabBarController并為其添加動(dòng)畫

    Swift自定義iOS中的TabBarController并為其添加動(dòng)畫

    這篇文章主要介紹了Swift自定義iOS中的TabBarController并為其添加動(dòng)畫的方法,即自定義TabBarController中的的TabBar并為自定義的TabBar增加動(dòng)畫效果,需要的朋友可以參考下
    2016-04-04
  • Swift自定義UITableViewCell背景色

    Swift自定義UITableViewCell背景色

    這篇文章主要為大家詳細(xì)介紹了Swift自定義UITableViewCell背景色,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • mac git xcrun error active developer path 錯(cuò)誤

    mac git xcrun error active developer path 錯(cuò)誤

    本文主要是講訴了如何解決在mac下使用git;xcode4.6的環(huán)境時(shí),出現(xiàn)了錯(cuò)誤(mac git xcrun error active developer path)的解決辦法,希望對(duì)大家有所幫助
    2014-09-09
  • 簡單了解Swift語言中的break和continue語句的用法

    簡單了解Swift語言中的break和continue語句的用法

    這篇文章主要簡單介紹了Swift語言中的break和continue語句的用法,與其他語言的一樣用于循環(huán)語句流程控制,需要的朋友可以參考下
    2015-11-11
  • SwiftUI?List在MacOS中的性能優(yōu)化示例

    SwiftUI?List在MacOS中的性能優(yōu)化示例

    這篇文章主要為大家介紹了SwiftUI?List在MacOS中的性能優(yōu)化示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • swift如何利用系統(tǒng)庫將漢字轉(zhuǎn)換為拼音詳解

    swift如何利用系統(tǒng)庫將漢字轉(zhuǎn)換為拼音詳解

    將漢字轉(zhuǎn)換為拼音更利于我們大家開發(fā)搜索功能,所以這篇文章主要給大家介紹了關(guān)于swift如何利用系統(tǒng)庫將漢字轉(zhuǎn)換為拼音的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-10-10
  • Swift?中的?RegexBuilder學(xué)習(xí)指南

    Swift?中的?RegexBuilder學(xué)習(xí)指南

    這篇文章主要為大家介紹了Swift中的RegexBuilder學(xué)習(xí)指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04

最新評(píng)論

稻城县| 苏尼特左旗| 陕西省| 鄯善县| 隆安县| 桦南县| 北川| 潍坊市| 庆安县| 历史| 北宁市| 扶风县| 怀来县| 黄冈市| 泰兴市| 韶关市| 龙陵县| 民丰县| 弥渡县| 白河县| 芜湖市| 阿合奇县| 乌兰浩特市| 高唐县| 平塘县| 凤城市| 临桂县| 黔江区| 奉节县| 金乡县| 岳西县| 绩溪县| 台山市| 秭归县| 满城县| 儋州市| 沾化县| 舒城县| 交口县| 铜川市| 来安县|