swift学习第十五天:闭包
闭包
闭包的介绍
- 闭包和OC中的block非常相似
- OC中的block是匿名的函数
- Swift中的闭包是一个特殊的函数
- block和闭包都经常用于回调
- 注意:闭包和block一样,第一次使用时可能不习惯它的语法,可以先按照使用简单的闭包,随着学习的深入,慢慢掌握其灵活的运用方法.
闭包的使用
block的用法回顾
- 定义网络请求的类
@interface HttpTool : NSObject
- (void)loadRequest:(void (^)())callBackBlock;
@end
@implementation HttpTool
- (void)loadRequest:(void (^)())callBackBlock
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"加载网络数据:%@", [NSThread currentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
callBackBlock();
});
});
}
@end
- 进行网络请求,请求到数据后利用block进行回调
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self.httpTool loadRequest:^{
NSLog(@"主线程中,将数据回调.%@", [NSThread currentThread]);
self.view.backgroundColor = [UIColor redColor];
}];
}
- block写法总结:
block的写法: 类型: 返回值(^block的名称)(block的参数) 值: ^(参数列表) { // 执行的代码 };
注意:在上述oc中的block中,在block语句块中设置self.view.backgroundColor = [UIColor redColor];不会产生循环引用,原因是,如图所示:
控制器中属性定义HttpTool,则控制器会对HttpTool有一个强引用,在block语句块中会对外部引用的变量产生一个强引用,所以block对控制器有一个强引用,但
HttpTool不会对block产生一个强引用,所以没有形成闭环,不会产生循环引用。若是解决循环引用可以用:__weak typeof(self) weakSelf = self;
typeof(self)意思是取self的类型,所以也可以:
__weak vc *weakSelf = self。
import UIKit class ViewController: UIViewController { // 1:使用类时不需要导入类的头文件,默认自己创建的类在同一个命名空间中,且属性定义一个类的时候,必须要有初始化时,要么在定义时初始化,要么在初始化方法中进行初始化 var httpTool : HttpTool = HttpTool() override func viewDidLoad() { super.viewDidLoad() } func btnClick() { print("btnClick") } //2:重写系统的方法必须加上override关键字 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { // 闭包的常规写法 // httpTool.loadData { () -> () in // print("加载数据完成,更新界面:", NSThread.currentThread()) // } // 闭包的简写:如果闭包是没有参数,并且没有返回值,那么闭包中 () -> () in 可以省略 // 开发中建议该写法 //3:闭包的循环引用:!相当于如果weakSelf不为空,则执行后面的代码,若为空值则不去执行后面设置背景色的代码 // 解决方案一: // weak var weakSelf = self // // httpTool.loadData { // print("加载数据完成,更新界面:", NSThread.currentThread()) // weakSelf!.view.backgroundColor = UIColor.redColor() // } // 解决方案二: // weak var weakSelf = self // httpTool.loadData {[weak self] () -> () in // print("加载数据完成,更新界面:", NSThread.currentThread()) // self!.view.backgroundColor = UIColor.redColor() // } // 解决方案三: // unowned关键字相当于__unsafe_unretained,指向一个内存地址,不管该对象是否被销毁.依然指向该内存地址 httpTool.loadData {[unowned self] () -> () in print("加载数据完成,更新界面:", Thread.current) self.view.backgroundColor = UIColor.red } } // 4:析构函数(相当于OC中dealloc方法) deinit { print("ViewController----deinit") } }