最近新接手了一個(gè)Swift項(xiàng)目润脸,花點(diǎn)時(shí)間做點(diǎn)小結(jié)眷唉,以做記錄
我的博客鏈接
Swift中定義一個(gè)基本函數(shù)
//定義一個(gè)函數(shù)梭灿,接收一個(gè)字符串,返回一個(gè)String類型的值
func test(name:String) -> String {
return ("輸出了\(name)")
}
//通用形式
func name(parameters) -> return type {
function body
}
Swift 中基本的閉包函數(shù)與OC中Block的相似點(diǎn)
904629-95160b50313b3606.png
帶參閉包
void (^test) (NSString *)=^(NSString *name){
NSLog(@"%@",name);
};
test(@"測(cè)試");
//對(duì)應(yīng)到swift的帶參閉包
let test={(_ name:String)->() in
// in 后面就是回調(diào)之后處理的函數(shù) 卵渴,相當(dāng)于是Block之后的{ }
print(name)
}
test("測(cè)試")
//通用形式
{
(parameters) -> returnType in
code
}
這里下劃線 _ 的作用用來忽略外部參數(shù)名李命,具體可以參考這篇文章
帶參函數(shù)定義
-(void)loadData:( void(^)(void) )completetion
{
completetion();
}
func loadData(completetion: ()->()) -> () {
completetion()
}
//樣式 func: ()->()
舉栗子,網(wǎng)絡(luò)數(shù)據(jù)獲取
- OC
//OC中Block傳值
-(void)loadData:( void(^)(NSArray *) )completetion
{
//這里暫時(shí)先忽略掉線程,簡單處理流译,重點(diǎn)在swift閉包
NSLog(@"耗時(shí)操作");
sleep(2);//模擬網(wǎng)絡(luò)請(qǐng)求
NSArray *arr=@[@"1",@"2"];
NSLog(@"主線程回調(diào)");
completetion(arr); //返回獲得的數(shù)據(jù)
}
調(diào)用:
[self loadData:^(NSArray *callBack){
NSLog(@"%@,%@",callBack[0],callBack[1]);
}];
輸出:
2017-03-22 18:48:45.273 tessst[3642:187462] 耗時(shí)操作
2017-03-22 18:48:47.345 tessst[3642:187462] 主線程更新
2017-03-22 18:48:47.346 tessst[3642:187462] 1,2
- Swift
//swift中閉包傳值
func loadDate(completion: @escaping (_ result : [String])->()) -> () {
//這里有一個(gè)很重要的參數(shù) @escaping逞怨,逃逸閉包
//簡單來說就是 閉包在這個(gè)函數(shù)結(jié)束前內(nèi)被調(diào)用,就是非逃逸閉包福澡,調(diào)用的地方超過了這函數(shù)的范圍叠赦,叫逃逸閉包
//一般網(wǎng)絡(luò)請(qǐng)求都是請(qǐng)求后一段時(shí)間這個(gè)閉包才執(zhí)行,所以都是逃逸閉包革砸。
// 在Swift3.0中所有的閉包都默認(rèn)為非逃逸閉包除秀,所以需要用@escaping來修飾
DispatchQueue.global().async {
print("耗時(shí)操作\(Thread.current)")
Thread.sleep(forTimeInterval: 2)
let json=["1","2"]
DispatchQueue.main.async {
print("主線程更新\(Thread.current)")
completion(json)
//函數(shù)在執(zhí)行完后倆秒,主線程才回調(diào)數(shù)據(jù)算利,超過了函數(shù)的范圍册踩,這里就是屬于逃逸閉包,如果不用@escaping效拭,編譯器是編譯不過的
}
}
}
主函數(shù)調(diào)用loadDate:
loadDate { (callBack) in
print("\(callBack)")
}
輸出值
耗時(shí)操作<NSThread: 0x608000069140>{number = 1, name = main}
主線程更新<NSThread: 0x608000069140>{number = 1, name = main}
1暂吉,2
循環(huán)引用
- 在Block中經(jīng)常會(huì)有循環(huán)引用的情況,Swift閉包中也一樣缎患,常用的解決方式有倆種
//第一種
weak var weakwelf=self
//套用oc的方式(__weak typedef(weakself)=self).
//這里要注意慕的,不能用 let ,因?yàn)閟elf可能會(huì)釋放指向nil挤渔,相當(dāng)于是一個(gè)可變值
//調(diào)可選項(xiàng)發(fā)送消息的時(shí)候 用 肮街? 解包 不用 !
pringt("weakself ?.view") 不用" weakself!.view"
//因?yàn)閺?qiáng)制解包一旦weakself=nil時(shí)會(huì)崩潰
//第二種判导,在調(diào)用時(shí)候
//[weak self]標(biāo)識(shí)在{}中所有的self都是弱引用
loadDate { [weak self] in
print(self?.view)
}
尾隨閉包
func someFunctionThatTakesAClosure(closure: () -> ()) {
// 函數(shù)體部分
}
// 以下是不使用尾隨閉包進(jìn)行函數(shù)調(diào)用
someFunctionThatTakesAClosure({
// 閉包主體部分
})
// 以下是使用尾隨閉包進(jìn)行函數(shù)調(diào)用
someFunctionThatTakesAClosure() {
// 閉包主體部分
}