IOS swift3.0 下閉包語(yǔ)法整理
IOS swift3.0 下閉包語(yǔ)法整理
一、閉包的概念
有oc基礎(chǔ)的都知道,閉包其實(shí)是oc里面的block,語(yǔ)法格式不一樣,但作用是一樣的。主要是用于callBack(異步回調(diào))或者兩個(gè)類之間的通信。它的本質(zhì)一個(gè)函數(shù),一個(gè)可執(zhí)行的代碼塊,只是這個(gè)函數(shù)是沒(méi)有名字的,也就是匿名函數(shù)。你也可以把他看作如 int、float一樣,是一種數(shù)據(jù)類型,一種可以作為參數(shù)傳遞的數(shù)據(jù)類型。
二、基本語(yǔ)法
1、閉包的聲明
//定義一個(gè)求和閉包 //閉包類型:(Int,Int)->(Int) let add:(Int,Int)->(Int) = { (a,b) in return a + b; } //執(zhí)行閉包,相當(dāng)于調(diào)用函數(shù) let result = add(1100, 200); //打印閉包返回值 print("result=\(result)");
閉包類型是由參數(shù)返回值決定,如上述add閉包類型為(Int,Int)->(Int),箭頭前面括號(hào)是參數(shù)類型,多個(gè)參數(shù)逗號(hào)隔開(kāi),箭頭后面括號(hào)返回值類型。
分析下上面代碼,“=”左邊的“ let add:(Int,Int)->(Int) ”意思是聲明一個(gè)add常量,add是一個(gè)閉包類型,并且這個(gè)閉包的類型是:(Int,Int)->(Int)。
“=”右邊是一個(gè)代碼塊,即閉包的具體實(shí)現(xiàn),相當(dāng)于給左邊add常量賦值。代碼塊的語(yǔ)法格式:
{ (參數(shù)1,參數(shù)2) in //code }
參數(shù)和需執(zhí)行的代碼(code)用 關(guān)鍵字“in”隔開(kāi),如果閉包沒(méi)有參數(shù), “ () in”可以直接省略:
{ //code }
你也可以用關(guān)鍵字“typealias”先聲明一個(gè)閉包的數(shù)據(jù)類型
import UIKit //聲明一個(gè)閉包類型 AddBlock typealias AddBlock = (Int,Int)->(Int); class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let add:AddBlock = { (a,b) in return a + b; } let result = add(1100, 200); print("result=\(result)"); } }
3、閉包的用法
1、兩個(gè)類之間的通信
ios中類之間的通信方式有多種,常用的有:協(xié)議代理、通知,以及本章要講的閉包。因?yàn)閰f(xié)議代理用起來(lái)比較麻煩,又是聲明協(xié)議方法、又要設(shè)置代理的,代碼步驟太多,我一般不用;通知一般用于兩個(gè)完全沒(méi)有關(guān)聯(lián)的類通信,可以一對(duì)多,但解耦和的太厲害,我一般是特定的場(chǎng)合用。所以針對(duì)有關(guān)聯(lián)的兩個(gè)類之間的通信,我一般是用閉包或block的,這樣比較簡(jiǎn)潔迅速。
示例程序:監(jiān)聽(tīng)控制器上一個(gè)自定義view按鈕的點(diǎn)擊
界面效果
CustomView類中代碼
class CustomView: UIView { //聲明一個(gè)屬性btnClickBlock,type為閉包可選類型 //閉包類型:()->() ,無(wú)參數(shù),無(wú)返回值 var btnClickBlock:(()->())?; //重寫(xiě) init(frame: CGRect)構(gòu)造函數(shù) override init(frame: CGRect) { super.init(frame:frame); //創(chuàng)建按鈕 let btn = UIButton(frame: CGRect(x: 15, y: 15, width: 80, height: 32)); btn.setTitle("按鈕", for: .normal); btn.backgroundColor = UIColor.blue; //綁定事件 btn.addTarget(self, action: #selector(CustomView.btnClick), for: .touchDown); //添加 addSubview(btn); } //按鈕點(diǎn)擊事件函數(shù) func btnClick(){ if self.btnClickBlock != nil { //點(diǎn)擊按鈕執(zhí)行閉包 //注意:屬性btnClickBlock是可選類型,需要先解包 self.btnClickBlock!(); } } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
Controller類中代碼:
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() //創(chuàng)建CustomView對(duì)象 let cutomeView = CustomView(frame: CGRect(x: 50, y: 50, width: 200, height: 200)); //給cutomeView的btnClickBlock閉包屬性賦值 cutomeView.btnClickBlock = { // () in 無(wú)參數(shù)可以省略 //當(dāng)按鈕被點(diǎn)擊時(shí)會(huì)執(zhí)行此代碼塊 print("按鈕被點(diǎn)擊"); } cutomeView.backgroundColor = UIColor.yellow; //添加到控制器view上 self.view.addSubview(cutomeView); } }
2、異步回調(diào)(callBack)
以發(fā)送一個(gè)簡(jiǎn)單的網(wǎng)絡(luò)請(qǐng)求為例:
/// 定義一個(gè)網(wǎng)絡(luò)請(qǐng)求函數(shù) /// /// - parameter urlString: 請(qǐng)求接口 String /// - parameter succeed: 成功的回調(diào) 可選閉包 /// - parameter failure: 失敗的回調(diào) 可選閉包 func requestData(urlString:String,succeed: ((Any?)->(Void))?,failure:((Any?)->(Void))?){ let request = URLRequest(url: URL(string: urlString)!); //發(fā)送網(wǎng)絡(luò)請(qǐng)求 NSURLConnection.sendAsynchronousRequest(request, queue: OperationQueue()) { (_, data, error) in if error == nil { //請(qǐng)求成功,執(zhí)行成功的回調(diào),并把數(shù)據(jù)傳遞出去 succeed?(data); }else{ //請(qǐng)求失敗,執(zhí)行失敗的回調(diào),并把錯(cuò)誤傳遞出去 failure?(error); } } }
// 調(diào)用函數(shù)requestData函數(shù) requestData(urlString: "http://www.baidu.com", succeed: { (data) -> (Void) in //成功的回調(diào) guard let result = data as? Data else{ return; } let srt = NSString(data: result, encoding: String.Encoding.utf8.rawValue); print(srt!) }) { (error) -> (Void) in //失敗的的回調(diào) print(error); }
四、閉包的一些特殊語(yǔ)法
1、尾隨閉包
當(dāng)閉包作為函數(shù)的最后一個(gè)參數(shù)時(shí),可以省略前面的括號(hào)。尾隨閉包沒(méi)什么特殊的作用,純粹是一種語(yǔ)法上的簡(jiǎn)潔,增加易讀性。
例:定義一個(gè)函數(shù):
//第二個(gè)參數(shù):閉包 (String)->(Void) func post(url:String,succesce:(String)->Void) { print("發(fā)送請(qǐng)求"); succesce("請(qǐng)求完成"); }
執(zhí)行函數(shù),正常寫(xiě)法:
//正常寫(xiě)法,第二個(gè)參數(shù),傳遞一個(gè)閉包 post("http", succesce: { //閉包傳遞的參數(shù) (json) in //執(zhí)行的代碼 print(json); });
執(zhí)行函數(shù),尾隨閉包寫(xiě)法:
//尾隨閉包,當(dāng)閉包作為函數(shù)的最后一個(gè)參數(shù)時(shí),可以省略前面的括號(hào) HttpTool.post("http") { (json) in print(json); };
2、逃逸閉包
看起來(lái)很“吊炸天”的一個(gè)名字,其實(shí)很簡(jiǎn)單。當(dāng)閉包作為一個(gè)參數(shù)傳遞到函數(shù)時(shí),我們知道它一般是用于函數(shù)內(nèi)部的異步回調(diào),閉包是等異步任務(wù)完成以后才調(diào)用,而函數(shù)是會(huì)很快執(zhí)行完畢并返回的,所以閉包它需要逃逸,以便稍后的回調(diào)。
逃逸閉包一般用于異步函數(shù)的回調(diào),比如網(wǎng)絡(luò)請(qǐng)求成功的回調(diào)和失敗的回調(diào)。語(yǔ)法:在函數(shù)的閉包行參前加關(guān)鍵字“@escaping”。
或許細(xì)心的人已經(jīng)發(fā)現(xiàn)我上面的示例網(wǎng)絡(luò)請(qǐng)求為什么沒(méi)有出現(xiàn)關(guān)鍵字“@escaping”,你可以拉回去看下成功回調(diào)或失敗的回調(diào),類型是“((Any?)->(Void))?”,后面帶了個(gè)“?”,這是閉包可選類型,并不是閉包類型,所以無(wú)需關(guān)鍵字“@escaping”。
假設(shè)成功和失敗的回調(diào)要弄成閉包類型,而你又要異步使用的話,那就要在形參前面加關(guān)鍵字,如下:
/// 定義一個(gè)網(wǎng)絡(luò)請(qǐng)求函數(shù) /// /// - parameter urlString: 請(qǐng)求接口 String /// - parameter succeed: 成功的回調(diào) 閉包 因需要異步使用,前面加關(guān)鍵字@escaping修飾,指明其為逃逸閉包 /// - parameter failure: 失敗的回調(diào) 閉包 因需要異步使用,前面加關(guān)鍵字@escaping修飾,指明其為逃逸閉包 func requestData(urlString:String,succeed: @escaping (Any?)->(Void),failure:@escaping (Any?)->(Void)){ let request = URLRequest(url: URL(string: urlString)!); //發(fā)送網(wǎng)絡(luò)請(qǐng)求 NSURLConnection.sendAsynchronousRequest(request, queue: OperationQueue()) { (_, data, error) in if error == nil { //請(qǐng)求成功,執(zhí)行成功的回調(diào),并把數(shù)據(jù)傳遞出去 succeed(data); }else{ //請(qǐng)求失敗,執(zhí)行失敗的回調(diào),并把錯(cuò)誤傳遞出去 failure(error); } } }
假設(shè)成功和失敗的回調(diào)要弄成閉包類型,而你又要異步使用的話,但你又不想在形參前面加關(guān)鍵字,那對(duì)不起,我也沒(méi)有辦法,編譯直接報(bào)錯(cuò)!
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
iOS 斷點(diǎn)上傳文件的實(shí)現(xiàn)方法
這項(xiàng)目開(kāi)發(fā)中,有時(shí)候我們需要將本地的文件上傳到服務(wù)器,簡(jiǎn)單的幾張圖片還好,但是針對(duì)iPhone里面的視頻文件進(jìn)行上傳,為了用戶體驗(yàn),我們有必要實(shí)現(xiàn)斷點(diǎn)上傳。這篇文章主要介紹了iOS 斷點(diǎn)上傳文件的實(shí)現(xiàn)方法,需要的朋友可以參考下2017-12-12Reactnative-iOS回調(diào)Javascript的方法
這篇文章主要介紹了Reactnative-iOS回調(diào)Javascript的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09iOS優(yōu)雅的將CALayer旋轉(zhuǎn)360度示例代碼
CALayer我們又稱它叫做層,CALayer類的概念與UIView非常類似,并且可以包含圖片、文本、背景色等。下面這篇文章主要給大家介紹了關(guān)于iOS如何優(yōu)雅的將CALayer旋轉(zhuǎn)360度的相關(guān)資料,文中通過(guò)示例代碼的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2018-01-01IOS 通訊錄的訪問(wèn)和修改的實(shí)現(xiàn)
這篇文章主要介紹了IOS 通訊錄的訪問(wèn)和修改的實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2017-06-06iOS中定位當(dāng)前位置坐標(biāo)及轉(zhuǎn)換為火星坐標(biāo)的方法
這篇文章主要介紹了iOS中獲取當(dāng)前位置坐標(biāo)及轉(zhuǎn)換為火星坐標(biāo)的方法,這里的火星坐標(biāo)指的是我國(guó)專門研制的一種加密的坐標(biāo)系統(tǒng)...需要的朋友可以參考下2016-02-02