手把手带你学习Swift3.0(28):闭包
2017-11-01 本文已影响0人
阿凡提说AI
1.oc中的block
ViewController.m
#import "ViewController.h"
#import "HttpTools.h"
@interface ViewController ()
@property (nonatomic, strong) HttpTools *tools;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tools = [[HttpTools alloc] init];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 闭包&控制器&HttpTools对象有没有形成循环引用
__weak ViewController *weakSelf = self;
[self.tools loadData:^(NSString *jsonData) {
// NSLog(@"在控制器中,拿到数据:%@", jsonData);
weakSelf.view.backgroundColor = [UIColor redColor];
}];
}
- (void)dealloc {
NSLog(@"ViewController -- dealloc");
}
@end
HttpTools.h
#import <Foundation/Foundation.h>
@interface HttpTools : NSObject
- (void)loadData:(void(^)(NSString *))finishedCallback;
@end
HttpTools.m
#import "HttpTools.h"
@interface HttpTools()
@property(nonatomic ,copy) void (^finishedCallback)(NSString *);
@end
@implementation HttpTools
- (void)loadData:(void (^)(NSString *))finishedCallback
{
self.finishedCallback = finishedCallback;
// 1.发送网络的异步请求
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"已经发送了网络请求:%@", [NSThread currentThread]);
// 2.回到主线程
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"回到主线程:%@", [NSThread currentThread]);
// 3.获取数据, 并且将数据回调出去
finishedCallback(@"json数据");
});
});
}
@end
2.swift中的闭包
HttpTools.swift
import UIKit
class HttpTools {
var finishedCallback : ((_ jsonData : String) -> ())?
// 闭包类型: (_ 参数列表) -> (返回值类型)
// @escaping : 逃逸的
func loadData(_ finishedCallback : @escaping (_ jsonData : String) -> ()) {
self.finishedCallback = finishedCallback
// 1.发送异步网络请求
DispatchQueue.global().async {
print("发送异步网络请求:\(Thread.current)")
DispatchQueue.main.sync {
print("回到主线程:\(Thread.current)")
finishedCallback("json数据")
}
}
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
var httpTools : HttpTools?
// 在swift中只要是对父类的方法进行重写, 必须在方法前加上override
override func viewDidLoad() {
super.viewDidLoad()
httpTools = HttpTools()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// 解决循环引用的方案:
// 解决方案一:
/*
weak var weakSelf : ViewController? = self
httpTools?.loadData({ (jsonData : String) in
weakSelf?.view.backgroundColor = UIColor.red
})
*/
// 解决方案二:
/*
httpTools?.loadData({[weak self] (jsonData : String) in
self?.view.backgroundColor = UIColor.red
})
*/
// 解决方案三:
// unowned --> unsafe_unretained(野指针)
httpTools?.loadData({[unowned self] (jsonData : String) in
self.view.backgroundColor = UIColor.red
})
// 尾随闭包的概念(不建议)
// 如果在函数中, 闭包是最后一个参数, 那么可以写成尾随闭包
httpTools?.loadData() {[unowned self] (jsonData : String) in
self.view.backgroundColor = UIColor.red
}
// 如果是唯一的参数, 也可以将前面的()省略掉
httpTools?.loadData {[unowned self] (jsonData : String) in
self.view.backgroundColor = UIColor.red
}
}
deinit {
print("ViewController -- deinit")
}
}