SWIFT閉包,介紹,使用(ALAMOFIRE封裝 非同步請求)
首先說明簡明扼要的說明一下:閉包,可以看做 JAVA中匿名函式。
我們來看APPLE文件:
一個函式,可以看做一個特殊的閉包
巢狀函式,是一個捕獲其所在函式中上下文的閉包
閉包表示式,是一個寫法奇特,可以捕獲上下文變數的【匿名閉包】
那麼讓我們開始:
我們有這樣子的一個需求:寫一個API,他需要兩個引數,第一個引數是一個 字串陣列,第二個引數是一個函式,
這個函式的作用是向陣列中的每一個人打招呼,你可以對她說HELLO,BOY,你也可以對她說:OH,MY GOD.同時返回一個新的陣列,這個陣列中包含了對每個人說的話
那麼我們需要怎麼做呢?如果是不知道有【閉包】的情況下
==========這裡的預備知識是:高階函式,將函式作為其他函式的引數or返回值=============
那麼現在我們用高階函式來寫:
首先將上面的函式合併為一個:用高階函式來做
func sayHellotoeverybody(person:[String],fu:(eachPerson:String)->String)->[String]{
var newArray = [String]()
for eachPerson in person {
newArray.append(fu(eachPerson))
}
return newArray
}
func sayhelloFunc(eachPerson:String)->String{
print(“hello, u are so nice\(eachPerson)”)
return “hello, u are so nice\(eachPerson)”
}
呼叫的時候直接用:
let newArray = sayHellotoeverybody([“shan”,”wenzheng”,”xiaolin”],fu:sayhelloFunc)
================================================接下來我們用閉包來做===========
func sayHellotoeverybody(person:[String],fu:(eachPerson:String)->String)->[String]{
var newArray = [String]()
for eachPerson in person {
newArray.append(fu(eachPerson))
}
return newArray
}
let newArray = sayHellotoeverybody([“dsfa”,”dsfa”,”dsaf”],fu:{(name)->String in
//這裡做你想要的操作,比如對他說你很漂亮或者很醜
//或者其他的業務操作
print(“u are so ugly\(name)”)
return “ u are so ugly \(name)"
})
總結:從上面的函式來看,閉包最後的效果就是:隱藏了對每個人說話的函式,逼格更高,嘻嘻,
感覺是不是 JAVA的匿名函式呢?
//對閉包的一些補充
//閉包可以儲存到變數中
let plus = {(a:Int,b:Int)->Int in
return a + b
}
//使用
let number = plus(3,5)
==================================
//閉包的型別推斷
let plus:Int = {a,b in
return a + b
}
//括號都TM的省略了
//省略return 關鍵字
//如果閉包內只有一句話,並且這句話 return someThing
//那麼可以省略return
let plus = {a,b in a + b}
//變態的省略形參名 和 in
let plus:Int = {return $0 * $0}
=> let plus:Int = {$0 * $1)}
//幾乎沒法閱讀了
===================================
當引數列表最後一個是 函式,那麼可以使用尾隨閉包,簡化寫法
myFunc(a:Int,b:Int,c:{閉包體})
可以修改為:
myFucn(a:Int,b:Int){
$0 * $1
}
===================================
===================================
閉包的應用(對非同步操作有很好的封裝)
在一個方法中,如果其中有非同步方法,比如說網路請求。
那麼宣告一個閉包,作為這個方法的最後一個引數。
當獲取到網路請求的數值之後,執行這個引數方法。
使這個引數方法中的引數 賦值 為 網路請求下來的資料
-------
那麼在呼叫網路請求方法的時候,當閉包中有內容就說明請求成功,
可以使用了。
================
接下來是對Alamofire的非同步封裝
================
/**
方法體內部是回撥方法,此方法無需設定代理
- parameter url:請求API的URL
- parameter params:引數列表:雜湊
- parameter getResultfunc:結果集
*/
classfunc getAPIresult(url:String,params:Dictionary<String,AnyObject>,getResultfunc:(ifComplieted:Bool,resultString:
Alamofire.request(Method.POST, url, parameters: params, encoding: ParameterEncoding.URL, headers: nil).responseString(encoding: NSUTF8StringEncoding, completionHandler: { (Response) -> Voidin
if((Response.resultasResult).isSuccess && Response.result.value != nil){
let stringValue = Response.result.value!
if(stringValue != MessageCloud.arrayNoItem && stringValue != MessageCloud.nullItemOtherLanguage && stringValue != MessageCloud.nullItemOtherLanguage){
let nsdata = stringValue.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
do{
let nowdicData = tryNSJSONSerialization.JSONObjectWithData(nsdata!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
if(nowdicData != nil){
//這裡處理之,所有返回資料型別第一層都是字典
if(nowdicData!["state"] as! String == "1"){
if(nowdicData!["data"] as? NSArray != nil) {
//陣列型別的資料
getResultfunc(ifComplieted: true,resultString: stringValue,resultNSDic: NSDictionary(),resultNSArray: nowdicData!["data"] as! NSArray)
}elseif(nowdicData!["data"] as? NSDictionary != nil){
getResultfunc(ifComplieted: true,resultString: stringValue,resultNSDic: nowdicData!["data"] as! NSDictionary,resultNSArray: NSArray())
}else{
//字串型別的資料
let returnStr = nowdicData!["data"] as? String
getResultfunc(ifComplieted: true,resultString: returnStr!,resultNSDic: NSDictionary(),resultNSArray: NSArray())
}
}else{
//返回錯誤資料 ERRMSG 字典中的KEY
getResultfunc(ifComplieted: true,resultString: nowdicData!["errmsg"] as! String,resultNSDic: NSDictionary(),resultNSArray: NSArray())
}
}
}catchlet error asNSError{
//這裡處理系統錯誤,非編碼錯誤,例如:找不到伺服器,404錯誤等
//這裡應該返回CATCH
getResultfunc(ifComplieted: true,resultString: "\(error)",resultNSDic: NSDictionary(),resultNSArray: NSArray())
}
}else{
//在汽車專案中不可能存在這種情況
getResultfunc(ifComplieted: true,resultString: MessageCloud.noItem,resultNSDic: NSDictionary(),resultNSArray: NSArray())
}
}else{
//非200CODE 返回值都在這裡處理,比如說 404
getResultfunc(ifComplieted: true,resultString: "非20x 返回值,應當檢視Response的確切說明!",resultNSDic: NSDictionary(),resultNSArray: NSArray())
}
})
}
==============呼叫:
AlamofiredelegateEntity.getAPIresult("\(GLOBAL_IPADDRESS_API)RentalLocation/GetChargingStation", params: ["UserID":"\(34)","UserLa":"\(45)","UserLo":"\(98)","MapLevel":"\(2)"]) { (ifComplieted, resultString, resultNSDic, resultNSArray) -> Voidin
if(ifComplieted){
print(resultString)
}
}