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")
    }
}


原文地址:https://www.cnblogs.com/cqb-learner/p/5886068.html