//1、首先看一下函数结构
func test(name:String) -> String {
return ("输出了\(name)")
}
//2、OC中的Block与Swift中的---带参数---闭包比较
//OC
void (^test) (NSString *)=^(NSString *name){
NSLog(@"%@",name);
};
test(@"测试");
//swift
let test={(_ name:String)->() in // in 后面就是回调之后处理的函数 ,相当于是Block之后的{ }
print(name)
}
test("测试")
//3、在函数中当做---参数进行传递---
//OC
-(void)loadData:( void(^)(void) )completetion
{
completetion();
}
比如:
-(void)loadData:( void(^)(NSArray *) )completetion
{
//这里暂时先忽略掉线程,简单处理,重点在swift闭包
NSLog(@"耗时操作");
sleep(2);//模拟网络请求
NSArray *arr=@[@"1",@"2"];
NSLog(@"主线程回调");
completetion(arr); //返回获得的数据
}
[self loadData:^(NSArray *callBack){
NSLog(@"%@,%@",callBack[0],callBack[1]);
}];
//Swift
func loadData(completetion: (返回值)->()) -> () {
completetion()
}
比如:
func loadDate(completion: @escaping (_ result : [String])->()) -> () {
//这里有一个很重要的参数 @escaping,逃逸闭包
//简单来说就是 闭包在这个函数结束前内被调用,就是非逃逸闭包,调用的地方超过了这函数的范围,叫逃逸闭包
//一般网络请求都是请求后一段时间这个闭包才执行,所以都是逃逸闭包。
// 在Swift3.0中所有的闭包都默认为非逃逸闭包,所以需要用@escaping来修饰
DispatchQueue.global().async {
print("耗时操作\(Thread.current)")
Thread.sleep(forTimeInterval: 2)
let json=["1","2"]
DispatchQueue.main.async {
print("主线程更新\(Thread.current)")
completion(json)
//函数在执行完后俩秒,主线程才回调数据,超过了函数的范围,这里就是属于逃逸闭包,如果不用@escaping,编译器是编译不过的
}
}
}
loadDate { (callBack) in
print("\(callBack)")
}
3、作为属性进行传递
//OC
简单,再次忽略,如有不懂,请Google
//Swift
其中作为属性进行传递时,可分为几种:
1> var blockProperty : (Int,Int) -> String = { _ , _ in return ""} // 带初始化方式
2> var blockPropertyNoReturn : (String) -> () = { _ in }
在使用时,不需要再判断其是否存在(if let .... {}),因为已经初始化
class BlockTest: NSObject {
var blockIvar : (String,String) -> String = {_ , _ in return ""}
func testBlcok() {
let result = blockIvar("wojiao","wjy")
print("我是Block作为属性进行传值的结果----\(result)")
}
}
3> typealias blockFunc = (String , String) -> (String)
import UIKit
typealias blockFunc = (String , String) -> (String)
class BlockTest: NSObject {
//var blockIvar: blockFunc?
//func testBlcok() {
//if blockIvar != nil {
//let result = blockIvar!("wojiao","wjy")
//print("我是Block作为属性进行船只的结果----\(result)")
//}
//}
var blockIvar: blockFunc!
func testBlcok() {
if blockIvar != nil {
let result = blockIvar("wojiao","wjy")
print("我是Block作为属性进行船只的结果----\(result)")
}
}
}
//测试闭包(block)
func blockTest() {
let blockTest = BlockTest()
blockTest.blockIvar = {(first:String , second:String) -> String in
return first+second
}
blockTest.testBlcok()
}
4、循环引用
//第一种
weak var weakwelf=self
//套用oc的方式(__weak typedef(weakself)=self).
//这里要注意,不能用 let ,因为self可能会释放指向nil,相当于是一个可变值
//调可选项发送消息的时候 用 ? 解包 不用 !
pringt("weakself ?.view") 不用" weakself!.view"
//因为强制解包一旦weakself=nil时会崩溃
//第二种
//[weak self]标识在{}中所有的self都是弱引用
loadDate { [weak self] in
print(self?.view)
}
5、尾随闭包
尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。可以使用尾随闭包来增强函数的可读性。
func someFunctionThatTakesAClosure(closure: () -> ()) {
// 函数体部分
}
// 以下是不使用尾随闭包进行函数调用
someFunctionThatTakesAClosure({
// 闭包主体部分
})
// 以下是使用尾随闭包进行函数调用
someFunctionThatTakesAClosure() {
// 闭包主体部分
}
Swift闭包
猜你喜欢
转载自blog.csdn.net/wjy0629/article/details/81252195
今日推荐
周排行